summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--WHATSNEW.txt6
-rw-r--r--docs/Samba-HOWTO-Collection.pdf6885
-rw-r--r--docs/docbook/Makefile.in4
-rw-r--r--docs/docbook/manpages/smb.conf.5.sgml54
-rw-r--r--docs/docbook/manpages/smbcontrol.1.sgml54
-rw-r--r--docs/docbook/projdoc/Samba-LDAP-HOWTO.sgml2
-rw-r--r--docs/docbook/projdoc/Samba-PDC-HOWTO.sgml2
-rw-r--r--docs/docbook/projdoc/samba-doc.sgml16
-rw-r--r--docs/docbook/projdoc/winbind.sgml192
-rw-r--r--docs/htmldocs/Integrating-with-Windows.html20
-rw-r--r--docs/htmldocs/Samba-HOWTO-Collection.html6741
-rw-r--r--docs/htmldocs/Samba-LDAP-HOWTO.html4
-rw-r--r--docs/htmldocs/Samba-PDC-HOWTO.html2
-rw-r--r--docs/htmldocs/UNIX_INSTALL.html29
-rw-r--r--docs/htmldocs/rpcclient.1.html43
-rw-r--r--docs/htmldocs/smb.conf.5.html1183
-rw-r--r--docs/htmldocs/smbcontrol.1.html69
-rw-r--r--docs/htmldocs/winbind.html260
-rw-r--r--docs/manpages/rpcclient.120
-rw-r--r--docs/manpages/smb.conf.5456
-rw-r--r--docs/manpages/smbcontrol.141
-rw-r--r--docs/textdocs/Samba-OpenSSL.txt405
-rw-r--r--docs/textdocs/Solaris-Winbind-HOWTO.txt361
-rw-r--r--examples/LDAP/samba.schema16
-rw-r--r--examples/VFS/Makefile37
-rw-r--r--examples/VFS/audit.c174
-rw-r--r--examples/VFS/block/Makefile37
-rw-r--r--examples/VFS/block/block.c144
-rw-r--r--examples/VFS/recycle.c139
-rw-r--r--examples/VFS/skel.c243
-rw-r--r--examples/pdb/README4
-rw-r--r--examples/pdb/pdb_test.c8
-rw-r--r--packaging/Caldera/OpenLinux/samba3.spec.tmpl26
-rw-r--r--source3/CodingSuggestions16
-rw-r--r--source3/Makefile.in49
-rw-r--r--source3/acconfig.h3
-rw-r--r--source3/auth/auth.c14
-rw-r--r--source3/auth/auth_domain.c139
-rw-r--r--source3/auth/auth_sam.c19
-rw-r--r--source3/auth/auth_util.c5
-rw-r--r--source3/auth/auth_winbind.c70
-rw-r--r--source3/bin/.cvsignore2
-rw-r--r--source3/client/clitar.c2
-rw-r--r--source3/client/smbmount.c3
-rw-r--r--source3/client/smbspool.c15
-rwxr-xr-xsource3/configure90
-rw-r--r--source3/configure.in31
-rw-r--r--source3/include/ads.h62
-rw-r--r--source3/include/config.h.in17
-rw-r--r--source3/include/includes.h2
-rw-r--r--source3/include/local.h14
-rw-r--r--source3/include/messages.h1
-rw-r--r--source3/include/nameserv.h2
-rw-r--r--source3/include/nt_printing.h32
-rw-r--r--source3/include/passdb.h4
-rw-r--r--source3/include/rpc_client_proto.h231
-rw-r--r--source3/include/rpc_lsa.h38
-rw-r--r--source3/include/rpc_reg.h108
-rw-r--r--source3/include/rpc_samr.h72
-rwxr-xr-xsource3/include/rpc_spoolss.h14
-rw-r--r--source3/include/rpc_srvsvc.h116
-rw-r--r--source3/include/secrets.h4
-rw-r--r--source3/include/sids.h (renamed from source3/python/py_conv.h)35
-rw-r--r--source3/include/smb.h27
-rw-r--r--source3/include/version.h2
-rw-r--r--source3/include/vfs.h201
-rw-r--r--source3/intl/lang_tdb.c6
-rw-r--r--source3/lib/account_pol.c88
-rw-r--r--source3/lib/charcnv.c19
-rw-r--r--source3/lib/debug.c8
-rw-r--r--source3/lib/domain_namemap.c1317
-rw-r--r--source3/lib/genrand.c2
-rw-r--r--source3/lib/replace.c2
-rw-r--r--source3/lib/smbrun.c2
-rw-r--r--source3/lib/substitute.c53
-rw-r--r--source3/lib/system.c10
-rw-r--r--source3/lib/username.c2
-rw-r--r--source3/lib/util.c38
-rw-r--r--source3/lib/util_getent.c21
-rw-r--r--source3/lib/util_sid.c3
-rw-r--r--source3/lib/util_sock.c2
-rw-r--r--source3/lib/util_str.c165
-rw-r--r--source3/lib/wins_srv.c2
-rw-r--r--source3/lib/xfile.c2
-rw-r--r--source3/libads/ads_struct.c107
-rw-r--r--source3/libads/kerberos.c12
-rw-r--r--source3/libads/kerberos_verify.c2
-rw-r--r--source3/libads/ldap.c389
-rw-r--r--source3/libads/ldap_user.c6
-rw-r--r--source3/libads/sasl.c9
-rw-r--r--source3/libads/util.c2
-rw-r--r--source3/libsmb/cli_dfs.c245
-rw-r--r--source3/libsmb/cli_lsarpc.c1168
-rw-r--r--source3/libsmb/cli_netlogon.c664
-rw-r--r--source3/libsmb/cli_pipe_util.c82
-rw-r--r--source3/libsmb/cli_reg.c102
-rw-r--r--source3/libsmb/cli_samr.c1294
-rw-r--r--source3/libsmb/cli_spoolss.c2156
-rw-r--r--source3/libsmb/cli_spoolss_notify.c223
-rw-r--r--source3/libsmb/cli_srvsvc.c442
-rw-r--r--source3/libsmb/cli_wkssvc.c93
-rw-r--r--source3/libsmb/cliconnect.c47
-rw-r--r--source3/libsmb/clispnego.c61
-rw-r--r--source3/libsmb/namequery.c67
-rw-r--r--source3/libsmb/smbencrypt.c16
-rw-r--r--source3/libsmb/trust_passwd.c2
-rw-r--r--source3/nmbd/asyncdns.c1
-rw-r--r--source3/nmbd/nmbd.c11
-rw-r--r--source3/nmbd/nmbd_become_dmb.c2
-rw-r--r--source3/nmbd/nmbd_mynames.c2
-rw-r--r--source3/nmbd/nmbd_nameregister.c22
-rw-r--r--source3/nmbd/nmbd_packets.c25
-rw-r--r--source3/nmbd/nmbd_processlogon.c113
-rw-r--r--source3/nsswitch/pam_winbind.c18
-rw-r--r--source3/nsswitch/wb_client.c6
-rw-r--r--source3/nsswitch/wb_common.c17
-rw-r--r--source3/nsswitch/wbinfo.c7
-rw-r--r--source3/nsswitch/winbindd.c7
-rw-r--r--source3/nsswitch/winbindd.h8
-rw-r--r--source3/nsswitch/winbindd_ads.c119
-rw-r--r--source3/nsswitch/winbindd_cache.c15
-rw-r--r--source3/nsswitch/winbindd_cm.c196
-rw-r--r--source3/nsswitch/winbindd_group.c6
-rw-r--r--source3/nsswitch/winbindd_nss.h12
-rw-r--r--source3/nsswitch/winbindd_pam.c139
-rw-r--r--source3/nsswitch/winbindd_proto.h142
-rw-r--r--source3/nsswitch/winbindd_rpc.c15
-rw-r--r--source3/nsswitch/winbindd_sid.c15
-rw-r--r--source3/nsswitch/winbindd_user.c3
-rw-r--r--source3/nsswitch/winbindd_util.c118
-rw-r--r--source3/nsswitch/winbindd_wins.c6
-rw-r--r--source3/param/loadparm.c96
-rw-r--r--source3/passdb/passdb.c158
-rw-r--r--source3/passdb/pdb_get_set.c11
-rw-r--r--source3/passdb/pdb_interface.c6
-rw-r--r--source3/passdb/pdb_ldap.c179
-rw-r--r--source3/passdb/pdb_nisplus.c16
-rw-r--r--source3/passdb/pdb_smbpasswd.c2
-rw-r--r--source3/passdb/pdb_tdb.c7
-rw-r--r--source3/passdb/pdb_unix.c29
-rw-r--r--source3/passdb/secrets.c62
-rw-r--r--source3/passdb/util_sam_sid.c3
-rw-r--r--source3/printing/load.c8
-rw-r--r--source3/printing/notify.c65
-rw-r--r--source3/printing/nt_printing.c825
-rw-r--r--source3/printing/pcap.c11
-rw-r--r--source3/printing/print_svid.c2
-rw-r--r--source3/printing/printfsp.c6
-rw-r--r--source3/printing/printing.c399
-rw-r--r--source3/python/.cvsignore1
-rwxr-xr-xsource3/python/examples/spoolss/changeid.py29
-rwxr-xr-xsource3/python/examples/spoolss/enumprinters.py25
-rwxr-xr-xsource3/python/examples/spoolss/psec.py87
-rwxr-xr-xsource3/python/gtdbtool282
-rw-r--r--source3/python/py_common.c255
-rw-r--r--source3/python/py_conv.c159
-rw-r--r--source3/python/py_samr.c456
-rw-r--r--source3/python/py_spoolss.c478
-rw-r--r--source3/python/py_spoolss_drivers.c434
-rw-r--r--source3/python/py_spoolss_drivers_conv.c148
-rw-r--r--source3/python/py_spoolss_forms.c266
-rw-r--r--source3/python/py_spoolss_jobs.c377
-rw-r--r--source3/python/py_spoolss_printerdata.c234
-rw-r--r--source3/python/py_spoolss_printers.c480
-rw-r--r--source3/python/py_spoolss_printers_conv.c296
-rw-r--r--source3/python/py_spoolss_proto.h120
-rw-r--r--source3/python/py_winbind.c651
-rw-r--r--source3/python/samba-head.patch69
-rwxr-xr-xsource3/python/setup.py.in163
-rw-r--r--source3/rpc_client/cli_login.c173
-rw-r--r--source3/rpc_client/cli_netlogon.c978
-rw-r--r--source3/rpc_client/cli_reg.c1118
-rw-r--r--source3/rpc_client/cli_samr.c1761
-rw-r--r--source3/rpc_client/cli_spoolss.c2602
-rw-r--r--source3/rpc_client/cli_spoolss_notify.c486
-rw-r--r--source3/rpc_client/cli_srvsvc.c727
-rw-r--r--source3/rpc_client/cli_wkssvc.c122
-rw-r--r--source3/rpc_client/msrpc_spoolss.c812
-rw-r--r--source3/rpc_client/ntclienttrust.c157
-rw-r--r--source3/rpc_parse/parse_lsa.c123
-rw-r--r--source3/rpc_parse/parse_net.c2
-rw-r--r--source3/rpc_parse/parse_prs.c8
-rw-r--r--source3/rpc_parse/parse_reg.c269
-rw-r--r--source3/rpc_parse/parse_samr.c88
-rw-r--r--source3/rpc_parse/parse_spoolss.c87
-rw-r--r--source3/rpc_parse/parse_srv.c703
-rw-r--r--source3/rpc_server/srv_lsa.c37
-rw-r--r--source3/rpc_server/srv_lsa_nt.c97
-rw-r--r--source3/rpc_server/srv_netlog_nt.c6
-rw-r--r--source3/rpc_server/srv_reg.c81
-rw-r--r--source3/rpc_server/srv_reg_nt.c730
-rw-r--r--source3/rpc_server/srv_samr.c40
-rw-r--r--source3/rpc_server/srv_samr_nt.c142
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c63
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c1103
-rw-r--r--source3/rpc_server/srv_srvsvc.c31
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c394
-rw-r--r--source3/rpc_server/srv_util.c62
-rw-r--r--source3/rpcclient/cmd_lsarpc.c67
-rw-r--r--source3/rpcclient/cmd_netlogon.c6
-rw-r--r--source3/rpcclient/cmd_samr.c75
-rw-r--r--source3/rpcclient/cmd_spoolss.c80
-rw-r--r--source3/rpcclient/cmd_srvsvc.c2
-rw-r--r--source3/rpcclient/rpcclient.c10
-rw-r--r--source3/rpcclient/samsync.c411
-rwxr-xr-xsource3/script/installman.sh4
-rw-r--r--source3/script/mkproto.awk2
-rwxr-xr-xsource3/script/mkproto.sh2
-rw-r--r--source3/smbd/blocking.c23
-rw-r--r--source3/smbd/chgpasswd.c8
-rw-r--r--source3/smbd/conn.c23
-rw-r--r--source3/smbd/connection.c8
-rw-r--r--source3/smbd/dir.c69
-rw-r--r--source3/smbd/dosmode.c92
-rw-r--r--source3/smbd/fileio.c2
-rw-r--r--source3/smbd/filename.c1
-rw-r--r--source3/smbd/lanman.c41
-rw-r--r--source3/smbd/mangle_hash2.c6
-rw-r--r--source3/smbd/negprot.c21
-rw-r--r--source3/smbd/nttrans.c960
-rw-r--r--source3/smbd/password.c36
-rw-r--r--source3/smbd/posix_acls.c2
-rw-r--r--source3/smbd/process.c21
-rw-r--r--source3/smbd/reply.c53
-rw-r--r--source3/smbd/server.c157
-rw-r--r--source3/smbd/service.c36
-rw-r--r--source3/smbd/session.c74
-rw-r--r--source3/smbd/sesssetup.c117
-rw-r--r--source3/smbd/ssl.c286
-rw-r--r--source3/smbd/trans2.c88
-rw-r--r--source3/smbd/uid.c86
-rw-r--r--source3/smbd/vfs.c147
-rw-r--r--source3/torture/locktest.c2
-rw-r--r--source3/torture/locktest2.c70
-rw-r--r--source3/utils/net.c5
-rw-r--r--source3/utils/net_ads.c141
-rw-r--r--source3/utils/net_lookup.c9
-rw-r--r--source3/utils/net_rpc.c368
-rw-r--r--source3/utils/net_rpc_join.c110
-rw-r--r--source3/utils/pdbedit.c316
-rw-r--r--source3/utils/smbcacls.c2
-rw-r--r--source3/utils/smbcontrol.c20
-rw-r--r--source3/utils/smbgroupedit.c4
-rw-r--r--source3/utils/smbpasswd.c6
-rw-r--r--source3/utils/smbtree.c2
-rw-r--r--source3/utils/status.c10
-rw-r--r--source3/utils/testparm.c9
-rw-r--r--source3/web/diagnose.c17
-rw-r--r--source3/web/neg_lang.c62
-rw-r--r--source3/web/startstop.c33
-rw-r--r--source3/web/statuspage.c28
-rw-r--r--source3/web/swat.c16
-rw-r--r--source3/wrepld/process.c2
-rw-r--r--source3/wrepld/server.c3
254 files changed, 23137 insertions, 30084 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index ba9956cdbb..3a30b7b1ef 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,12 +1,6 @@
WHATS NEW IN Samba 3.0 alphaX
=============================
-Changes in alpha18
- - huge number of changes! really too many to list ... (and its 1am
- here, and I'm too tired)
- See the cvs tree at http://build.samba.org/
-
-
Changes in alpha17
- OpenLinux packaging updates (jht)
- Locking updates - fix zero timeout (tridge, jra)
diff --git a/docs/Samba-HOWTO-Collection.pdf b/docs/Samba-HOWTO-Collection.pdf
index e47621a0b8..2d9a2009ac 100644
--- a/docs/Samba-HOWTO-Collection.pdf
+++ b/docs/Samba-HOWTO-Collection.pdf
@@ -1,6 +1,6 @@
%PDF-1.2
%âãÏÓ
-1 0 obj<</Producer(htmldoc 1.8.11 Copyright 1997-2001 Easy Software Products, All Rights Reserved.)/CreationDate(D:20020815182605Z)/Title(SAMBA Project Documentation)/Creator(Modular DocBook HTML Stylesheet Version 1.57)>>endobj
+1 0 obj<</Producer(htmldoc 1.8.11 Copyright 1997-2001 Easy Software Products, All Rights Reserved.)/CreationDate(D:20020401145915Z)/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
@@ -26,511 +26,504 @@
21 0 obj<</Subtype/Link/Rect[369.9 587.8 471.0 600.8]/Border[0 0 0]/A 20 0 R>>endobj
22 0 obj[21 0 R
]endobj
-23 0 obj<</S/URI/URI(mailto:samba@samba.org)>>endobj
-24 0 obj<</Subtype/Link/Rect[167.0 677.8 250.8 690.8]/Border[0 0 0]/A 23 0 R>>endobj
-25 0 obj<</S/URI/URI(http://samba.org/samba)>>endobj
-26 0 obj<</Subtype/Link/Rect[238.5 664.6 344.2 677.6]/Border[0 0 0]/A 25 0 R>>endobj
-27 0 obj[24 0 R
+23 0 obj<</S/URI/URI(ENCRYPTION.html)>>endobj
+24 0 obj<</Subtype/Link/Rect[176.8 381.8 270.6 394.8]/Border[0 0 0]/A 23 0 R>>endobj
+25 0 obj<</S/URI/URI(#PASSWORDLEVEL)>>endobj
+26 0 obj<</Subtype/Link/Rect[73.0 118.8 154.0 129.8]/Border[0 0 0]/A 25 0 R>>endobj
+27 0 obj<</S/URI/URI(#USERNAMELEVEL)>>endobj
+28 0 obj<</Subtype/Link/Rect[73.0 108.0 148.6 119.0]/Border[0 0 0]/A 27 0 R>>endobj
+29 0 obj[24 0 R
26 0 R
+28 0 R
]endobj
-28 0 obj<</S/URI/URI(ENCRYPTION.html)>>endobj
-29 0 obj<</Subtype/Link/Rect[176.8 381.8 270.6 394.8]/Border[0 0 0]/A 28 0 R>>endobj
-30 0 obj<</S/URI/URI(#PASSWORDLEVEL)>>endobj
-31 0 obj<</Subtype/Link/Rect[73.0 118.8 154.0 129.8]/Border[0 0 0]/A 30 0 R>>endobj
-32 0 obj<</S/URI/URI(#USERNAMELEVEL)>>endobj
-33 0 obj<</Subtype/Link/Rect[73.0 108.0 148.6 119.0]/Border[0 0 0]/A 32 0 R>>endobj
-34 0 obj[29 0 R
-31 0 R
+30 0 obj<</S/URI/URI(winbind.html)>>endobj
+31 0 obj<</Subtype/Link/Rect[508.9 602.2 547.4 615.2]/Border[0 0 0]/A 30 0 R>>endobj
+32 0 obj<</S/URI/URI(winbind.html)>>endobj
+33 0 obj<</Subtype/Link/Rect[72.0 589.0 115.4 602.0]/Border[0 0 0]/A 32 0 R>>endobj
+34 0 obj[31 0 R
33 0 R
]endobj
-35 0 obj<</S/URI/URI(winbind.html)>>endobj
-36 0 obj<</Subtype/Link/Rect[508.9 602.2 547.4 615.2]/Border[0 0 0]/A 35 0 R>>endobj
-37 0 obj<</S/URI/URI(winbind.html)>>endobj
-38 0 obj<</Subtype/Link/Rect[72.0 589.0 115.4 602.0]/Border[0 0 0]/A 37 0 R>>endobj
-39 0 obj[36 0 R
-38 0 R
+35 0 obj<</S/URI/URI(http://rsync.samba.org/)>>endobj
+36 0 obj<</Subtype/Link/Rect[120.9 89.0 222.3 102.0]/Border[0 0 0]/A 35 0 R>>endobj
+37 0 obj[36 0 R
]endobj
-40 0 obj<</S/URI/URI(http://rsync.samba.org/)>>endobj
-41 0 obj<</Subtype/Link/Rect[120.9 89.0 222.3 102.0]/Border[0 0 0]/A 40 0 R>>endobj
-42 0 obj[41 0 R
+38 0 obj<</S/URI/URI(#OBEYPAMRESTRICTIONS)>>endobj
+39 0 obj<</Subtype/Link/Rect[238.2 649.4 332.9 662.4]/Border[0 0 0]/A 38 0 R>>endobj
+40 0 obj<</S/URI/URI(#ENCRYPTPASSWORDS)>>endobj
+41 0 obj<</Subtype/Link/Rect[344.2 570.2 454.9 583.2]/Border[0 0 0]/A 40 0 R>>endobj
+42 0 obj[39 0 R
+41 0 R
]endobj
-43 0 obj<</S/URI/URI(#OBEYPAMRESTRICTIONS)>>endobj
-44 0 obj<</Subtype/Link/Rect[238.2 649.4 332.9 662.4]/Border[0 0 0]/A 43 0 R>>endobj
-45 0 obj<</S/URI/URI(#ENCRYPTPASSWORDS)>>endobj
-46 0 obj<</Subtype/Link/Rect[344.2 570.2 454.9 583.2]/Border[0 0 0]/A 45 0 R>>endobj
-47 0 obj[44 0 R
+43 0 obj<</S/URI/URI(http://www.microsoft.com/NTServer/nts/downloads/winfeatures/NTSDistrFile/AdminGuide.asp)>>endobj
+44 0 obj<</Subtype/Link/Rect[72.0 590.2 183.5 603.2]/Border[0 0 0]/A 43 0 R>>endobj
+45 0 obj<</S/URI/URI(#HOSTMSDFS)>>endobj
+46 0 obj<</Subtype/Link/Rect[347.8 511.0 420.4 524.0]/Border[0 0 0]/A 45 0 R>>endobj
+47 0 obj<</S/URI/URI(#MSDFSROOT)>>endobj
+48 0 obj<</Subtype/Link/Rect[383.6 497.8 456.2 510.8]/Border[0 0 0]/A 47 0 R>>endobj
+49 0 obj[44 0 R
46 0 R
+48 0 R
]endobj
-48 0 obj<</S/URI/URI(http://www.microsoft.com/NTServer/nts/downloads/winfeatures/NTSDistrFile/AdminGuide.asp)>>endobj
-49 0 obj<</Subtype/Link/Rect[72.0 590.2 183.5 603.2]/Border[0 0 0]/A 48 0 R>>endobj
-50 0 obj<</S/URI/URI(#HOSTMSDFS)>>endobj
-51 0 obj<</Subtype/Link/Rect[347.8 511.0 420.4 524.0]/Border[0 0 0]/A 50 0 R>>endobj
-52 0 obj<</S/URI/URI(#MSDFSROOT)>>endobj
-53 0 obj<</Subtype/Link/Rect[383.6 497.8 456.2 510.8]/Border[0 0 0]/A 52 0 R>>endobj
-54 0 obj[49 0 R
-51 0 R
-53 0 R
+50 0 obj<</S/URI/URI(#NTACLSUPPORT)>>endobj
+51 0 obj<</Subtype/Link/Rect[342.7 533.8 441.7 546.8]/Border[0 0 0]/A 50 0 R>>endobj
+52 0 obj[51 0 R
]endobj
-55 0 obj<</S/URI/URI(#NTACLSUPPORT)>>endobj
-56 0 obj<</Subtype/Link/Rect[342.7 533.8 441.7 546.8]/Border[0 0 0]/A 55 0 R>>endobj
-57 0 obj[56 0 R
+53 0 obj<</S/URI/URI(#SECURITYMASK)>>endobj
+54 0 obj<</Subtype/Link/Rect[88.2 668.2 180.6 681.2]/Border[0 0 0]/A 53 0 R>>endobj
+55 0 obj<</S/URI/URI(#CREATEMASK)>>endobj
+56 0 obj<</Subtype/Link/Rect[358.9 589.0 438.1 602.0]/Border[0 0 0]/A 55 0 R>>endobj
+57 0 obj<</S/URI/URI(#FORCESECURITYMODE)>>endobj
+58 0 obj<</Subtype/Link/Rect[427.0 536.2 526.0 549.2]/Border[0 0 0]/A 57 0 R>>endobj
+59 0 obj<</S/URI/URI(#FORCESECURITYMODE)>>endobj
+60 0 obj<</Subtype/Link/Rect[72.0 523.0 98.4 536.0]/Border[0 0 0]/A 59 0 R>>endobj
+61 0 obj<</S/URI/URI(#FORCECREATEMODE)>>endobj
+62 0 obj<</Subtype/Link/Rect[358.9 443.8 477.7 456.8]/Border[0 0 0]/A 61 0 R>>endobj
+63 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
+64 0 obj<</Subtype/Link/Rect[72.0 166.6 151.2 179.6]/Border[0 0 0]/A 63 0 R>>endobj
+65 0 obj[54 0 R
+56 0 R
+58 0 R
+60 0 R
+62 0 R
+64 0 R
]endobj
-58 0 obj<</S/URI/URI(#SECURITYMASK)>>endobj
-59 0 obj<</Subtype/Link/Rect[88.2 668.2 180.6 681.2]/Border[0 0 0]/A 58 0 R>>endobj
-60 0 obj<</S/URI/URI(#CREATEMASK)>>endobj
-61 0 obj<</Subtype/Link/Rect[358.9 589.0 438.1 602.0]/Border[0 0 0]/A 60 0 R>>endobj
-62 0 obj<</S/URI/URI(#FORCESECURITYMODE)>>endobj
-63 0 obj<</Subtype/Link/Rect[427.0 536.2 526.0 549.2]/Border[0 0 0]/A 62 0 R>>endobj
-64 0 obj<</S/URI/URI(#FORCESECURITYMODE)>>endobj
-65 0 obj<</Subtype/Link/Rect[72.0 523.0 98.4 536.0]/Border[0 0 0]/A 64 0 R>>endobj
-66 0 obj<</S/URI/URI(#FORCECREATEMODE)>>endobj
-67 0 obj<</Subtype/Link/Rect[358.9 443.8 477.7 456.8]/Border[0 0 0]/A 66 0 R>>endobj
-68 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
-69 0 obj<</Subtype/Link/Rect[72.0 166.6 151.2 179.6]/Border[0 0 0]/A 68 0 R>>endobj
-70 0 obj[59 0 R
-61 0 R
-63 0 R
-65 0 R
-67 0 R
+66 0 obj<</S/URI/URI(http://imprints.sourceforge.net)>>endobj
+67 0 obj<</Subtype/Link/Rect[146.5 548.2 280.3 561.2]/Border[0 0 0]/A 66 0 R>>endobj
+68 0 obj<</S/URI/URI(http://msdn.microsoft.com/)>>endobj
+69 0 obj<</Subtype/Link/Rect[221.4 521.8 341.1 534.8]/Border[0 0 0]/A 68 0 R>>endobj
+70 0 obj<</S/URI/URI(http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP)>>endobj
+71 0 obj<</Subtype/Link/Rect[72.0 297.4 355.9 310.4]/Border[0 0 0]/A 70 0 R>>endobj
+72 0 obj[67 0 R
69 0 R
+71 0 R
]endobj
-71 0 obj<</S/URI/URI(http://imprints.sourceforge.net)>>endobj
-72 0 obj<</Subtype/Link/Rect[146.5 548.2 280.3 561.2]/Border[0 0 0]/A 71 0 R>>endobj
-73 0 obj<</S/URI/URI(http://msdn.microsoft.com/)>>endobj
-74 0 obj<</Subtype/Link/Rect[221.4 521.8 341.1 534.8]/Border[0 0 0]/A 73 0 R>>endobj
-75 0 obj<</S/URI/URI(http://support.microsoft.com/support/kb/articles/Q189/1/05.ASP)>>endobj
-76 0 obj<</Subtype/Link/Rect[72.0 297.4 355.9 310.4]/Border[0 0 0]/A 75 0 R>>endobj
-77 0 obj[72 0 R
-74 0 R
-76 0 R
+73 0 obj<</Subtype/Link/Rect[462.9 705.8 540.9 718.8]/Border[0 0 0]/Dest[741 0 R/XYZ null 768 0]>>endobj
+74 0 obj<</S/URI/URI(#WRITELIST)>>endobj
+75 0 obj<</Subtype/Link/Rect[91.9 313.4 157.9 326.4]/Border[0 0 0]/A 74 0 R>>endobj
+76 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
+77 0 obj<</Subtype/Link/Rect[192.7 300.2 294.1 313.2]/Border[0 0 0]/A 76 0 R>>endobj
+78 0 obj<</S/URI/URI(#GUESTOK)>>endobj
+79 0 obj<</Subtype/Link/Rect[163.3 273.8 231.3 286.8]/Border[0 0 0]/A 78 0 R>>endobj
+80 0 obj<</S/URI/URI(#MAPTOGUEST)>>endobj
+81 0 obj<</Subtype/Link/Rect[401.4 168.2 492.0 181.2]/Border[0 0 0]/A 80 0 R>>endobj
+82 0 obj<</S/URI/URI(#MAPTOGUEST)>>endobj
+83 0 obj<</Subtype/Link/Rect[108.0 155.0 130.0 168.0]/Border[0 0 0]/A 82 0 R>>endobj
+84 0 obj[73 0 R
+75 0 R
+77 0 R
+79 0 R
+81 0 R
+83 0 R
]endobj
-78 0 obj<</Subtype/Link/Rect[462.9 705.8 540.9 718.8]/Border[0 0 0]/Dest[915 0 R/XYZ null 768 0]>>endobj
-79 0 obj<</S/URI/URI(#WRITELIST)>>endobj
-80 0 obj<</Subtype/Link/Rect[91.9 313.4 157.9 326.4]/Border[0 0 0]/A 79 0 R>>endobj
-81 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
-82 0 obj<</Subtype/Link/Rect[192.7 300.2 294.1 313.2]/Border[0 0 0]/A 81 0 R>>endobj
-83 0 obj<</S/URI/URI(#GUESTOK)>>endobj
-84 0 obj<</Subtype/Link/Rect[163.3 273.8 231.3 286.8]/Border[0 0 0]/A 83 0 R>>endobj
-85 0 obj<</S/URI/URI(#MAPTOGUEST)>>endobj
-86 0 obj<</Subtype/Link/Rect[401.4 168.2 492.0 181.2]/Border[0 0 0]/A 85 0 R>>endobj
-87 0 obj<</S/URI/URI(#MAPTOGUEST)>>endobj
-88 0 obj<</Subtype/Link/Rect[108.0 155.0 130.0 168.0]/Border[0 0 0]/A 87 0 R>>endobj
-89 0 obj[78 0 R
-80 0 R
-82 0 R
-84 0 R
-86 0 R
-88 0 R
+85 0 obj<</S/URI/URI(#PRINTERADMIN)>>endobj
+86 0 obj<</Subtype/Link/Rect[433.8 567.8 526.2 580.8]/Border[0 0 0]/A 85 0 R>>endobj
+87 0 obj[86 0 R
]endobj
-90 0 obj<</S/URI/URI(#PRINTERADMIN)>>endobj
-91 0 obj<</Subtype/Link/Rect[433.8 567.8 526.2 580.8]/Border[0 0 0]/A 90 0 R>>endobj
-92 0 obj[91 0 R
+88 0 obj<</S/URI/URI(rpcclient.1.html)>>endobj
+89 0 obj<</Subtype/Link/Rect[239.1 583.4 382.1 596.4]/Border[0 0 0]/A 88 0 R>>endobj
+90 0 obj<</S/URI/URI(#SHOWADDPRINTERWIZARD)>>endobj
+91 0 obj<</Subtype/Link/Rect[108.0 159.0 306.0 172.0]/Border[0 0 0]/A 90 0 R>>endobj
+92 0 obj<</S/URI/URI(#ADDPRINTERCOMMAND)>>endobj
+93 0 obj<</Subtype/Link/Rect[456.6 132.6 535.8 145.6]/Border[0 0 0]/A 92 0 R>>endobj
+94 0 obj<</S/URI/URI(#ADDPRINTERCOMMAND)>>endobj
+95 0 obj<</Subtype/Link/Rect[72.0 119.4 118.2 132.4]/Border[0 0 0]/A 94 0 R>>endobj
+96 0 obj[89 0 R
+91 0 R
+93 0 R
+95 0 R
]endobj
-93 0 obj<</S/URI/URI(rpcclient.1.html)>>endobj
-94 0 obj<</Subtype/Link/Rect[239.1 583.4 382.1 596.4]/Border[0 0 0]/A 93 0 R>>endobj
-95 0 obj<</S/URI/URI(#SHOWADDPRINTERWIZARD)>>endobj
-96 0 obj<</Subtype/Link/Rect[108.0 159.0 306.0 172.0]/Border[0 0 0]/A 95 0 R>>endobj
-97 0 obj<</S/URI/URI(#ADDPRINTERCOMMAND)>>endobj
-98 0 obj<</Subtype/Link/Rect[456.6 132.6 535.8 145.6]/Border[0 0 0]/A 97 0 R>>endobj
-99 0 obj<</S/URI/URI(#ADDPRINTERCOMMAND)>>endobj
-100 0 obj<</Subtype/Link/Rect[72.0 119.4 118.2 132.4]/Border[0 0 0]/A 99 0 R>>endobj
-101 0 obj[94 0 R
-96 0 R
-98 0 R
+97 0 obj<</S/URI/URI(#DELETEPRINTERCOMMAND)>>endobj
+98 0 obj<</Subtype/Link/Rect[189.3 681.4 334.5 694.4]/Border[0 0 0]/A 97 0 R>>endobj
+99 0 obj<</S/URI/URI(#ENUMPORTSCOMMAND)>>endobj
+100 0 obj<</Subtype/Link/Rect[451.4 504.2 510.8 517.2]/Border[0 0 0]/A 99 0 R>>endobj
+101 0 obj<</S/URI/URI(#ENUMPORTSCOMMAND)>>endobj
+102 0 obj<</Subtype/Link/Rect[72.0 491.0 118.2 504.0]/Border[0 0 0]/A 101 0 R>>endobj
+103 0 obj<</S/URI/URI(http://imprints.sourceforge.net/)>>endobj
+104 0 obj<</Subtype/Link/Rect[303.3 406.2 442.9 419.2]/Border[0 0 0]/A 103 0 R>>endobj
+105 0 obj[98 0 R
100 0 R
+102 0 R
+104 0 R
]endobj
-102 0 obj<</S/URI/URI(#DELETEPRINTERCOMMAND)>>endobj
-103 0 obj<</Subtype/Link/Rect[189.3 681.4 334.5 694.4]/Border[0 0 0]/A 102 0 R>>endobj
-104 0 obj<</S/URI/URI(#ENUMPORTSCOMMAND)>>endobj
-105 0 obj<</Subtype/Link/Rect[451.4 504.2 510.8 517.2]/Border[0 0 0]/A 104 0 R>>endobj
-106 0 obj<</S/URI/URI(#ENUMPORTSCOMMAND)>>endobj
-107 0 obj<</Subtype/Link/Rect[72.0 491.0 118.2 504.0]/Border[0 0 0]/A 106 0 R>>endobj
-108 0 obj<</S/URI/URI(http://imprints.sourceforge.net/)>>endobj
-109 0 obj<</Subtype/Link/Rect[303.3 406.2 442.9 419.2]/Border[0 0 0]/A 108 0 R>>endobj
-110 0 obj[103 0 R
-105 0 R
-107 0 R
-109 0 R
+106 0 obj<</S/URI/URI(http://imprints.sourceforge.net/)>>endobj
+107 0 obj<</Subtype/Link/Rect[108.0 479.8 244.9 492.8]/Border[0 0 0]/A 106 0 R>>endobj
+108 0 obj[107 0 R
]endobj
-111 0 obj<</S/URI/URI(http://imprints.sourceforge.net/)>>endobj
-112 0 obj<</Subtype/Link/Rect[108.0 479.8 244.9 492.8]/Border[0 0 0]/A 111 0 R>>endobj
-113 0 obj[112 0 R
+109 0 obj<</S/URI/URI(smbpasswd.8.html)>>endobj
+110 0 obj<</Subtype/Link/Rect[221.4 455.8 287.7 468.8]/Border[0 0 0]/A 109 0 R>>endobj
+111 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
+112 0 obj<</Subtype/Link/Rect[353.1 139.0 425.7 152.0]/Border[0 0 0]/A 111 0 R>>endobj
+113 0 obj<</S/URI/URI(#SECURITY)>>endobj
+114 0 obj<</Subtype/Link/Rect[169.1 99.4 241.7 112.4]/Border[0 0 0]/A 113 0 R>>endobj
+115 0 obj[110 0 R
+112 0 R
+114 0 R
]endobj
-114 0 obj<</S/URI/URI(#SECURITY)>>endobj
-115 0 obj<</Subtype/Link/Rect[73.0 617.6 116.2 628.6]/Border[0 0 0]/A 114 0 R>>endobj
-116 0 obj<</S/URI/URI(DOMAIN_MEMBER.html)>>endobj
-117 0 obj<</Subtype/Link/Rect[72.0 578.2 193.3 591.2]/Border[0 0 0]/A 116 0 R>>endobj
-118 0 obj<</S/URI/URI(ADS-HOWTO.html)>>endobj
-119 0 obj<</Subtype/Link/Rect[372.4 565.0 464.5 578.0]/Border[0 0 0]/A 118 0 R>>endobj
-120 0 obj[115 0 R
-117 0 R
+116 0 obj<</S/URI/URI(#WORKGROUP)>>endobj
+117 0 obj<</Subtype/Link/Rect[146.2 721.0 225.4 734.0]/Border[0 0 0]/A 116 0 R>>endobj
+118 0 obj<</S/URI/URI(#ENCRYPTPASSWORDS)>>endobj
+119 0 obj<</Subtype/Link/Rect[224.7 641.8 343.5 654.8]/Border[0 0 0]/A 118 0 R>>endobj
+120 0 obj<</S/URI/URI(#PASSWORDSERVER)>>endobj
+121 0 obj<</Subtype/Link/Rect[188.7 602.2 307.5 615.2]/Border[0 0 0]/A 120 0 R>>endobj
+122 0 obj[117 0 R
119 0 R
+121 0 R
]endobj
-121 0 obj<</S/URI/URI(smbpasswd.8.html)>>endobj
-122 0 obj<</Subtype/Link/Rect[221.4 455.8 287.7 468.8]/Border[0 0 0]/A 121 0 R>>endobj
-123 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
-124 0 obj<</Subtype/Link/Rect[353.1 139.0 425.7 152.0]/Border[0 0 0]/A 123 0 R>>endobj
-125 0 obj<</S/URI/URI(#SECURITY)>>endobj
-126 0 obj<</Subtype/Link/Rect[169.1 99.4 241.7 112.4]/Border[0 0 0]/A 125 0 R>>endobj
-127 0 obj[122 0 R
-124 0 R
+123 0 obj<</S/URI/URI(#SECURITYEQUALSSERVER)>>endobj
+124 0 obj<</Subtype/Link/Rect[277.9 721.0 354.1 734.0]/Border[0 0 0]/A 123 0 R>>endobj
+125 0 obj<</S/URI/URI(winbind.html)>>endobj
+126 0 obj<</Subtype/Link/Rect[153.9 668.2 222.3 681.2]/Border[0 0 0]/A 125 0 R>>endobj
+127 0 obj<</S/URI/URI(http://www.linuxworld.com)>>endobj
+128 0 obj<</Subtype/Link/Rect[443.5 351.4 500.6 364.4]/Border[0 0 0]/A 127 0 R>>endobj
+129 0 obj<</S/URI/URI(http://www.linuxworld.com/linuxworld/lw-1998-10/lw-10-samba.html)>>endobj
+130 0 obj<</Subtype/Link/Rect[72.0 338.2 189.3 351.2]/Border[0 0 0]/A 129 0 R>>endobj
+131 0 obj[124 0 R
126 0 R
+128 0 R
+130 0 R
]endobj
-128 0 obj<</S/URI/URI(#WORKGROUP)>>endobj
-129 0 obj<</Subtype/Link/Rect[146.2 721.0 225.4 734.0]/Border[0 0 0]/A 128 0 R>>endobj
-130 0 obj<</S/URI/URI(#ENCRYPTPASSWORDS)>>endobj
-131 0 obj<</Subtype/Link/Rect[224.7 641.8 343.5 654.8]/Border[0 0 0]/A 130 0 R>>endobj
-132 0 obj<</S/URI/URI(#PASSWORDSERVER)>>endobj
-133 0 obj<</Subtype/Link/Rect[188.7 602.2 307.5 615.2]/Border[0 0 0]/A 132 0 R>>endobj
-134 0 obj[129 0 R
-131 0 R
-133 0 R
+132 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
+133 0 obj<</Subtype/Link/Rect[182.3 603.4 254.9 616.4]/Border[0 0 0]/A 132 0 R>>endobj
+134 0 obj<</S/URI/URI(ENCRYPTION.html)>>endobj
+135 0 obj<</Subtype/Link/Rect[334.9 603.4 418.9 616.4]/Border[0 0 0]/A 134 0 R>>endobj
+136 0 obj<</S/URI/URI(UNIX_INSTALL.html)>>endobj
+137 0 obj<</Subtype/Link/Rect[339.0 439.4 443.5 452.4]/Border[0 0 0]/A 136 0 R>>endobj
+138 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
+139 0 obj<</Subtype/Link/Rect[445.9 426.2 544.6 439.2]/Border[0 0 0]/A 138 0 R>>endobj
+140 0 obj[133 0 R
+135 0 R
+137 0 R
+139 0 R
]endobj
-135 0 obj<</S/URI/URI(#SECURITYEQUALSSERVER)>>endobj
-136 0 obj<</Subtype/Link/Rect[277.9 721.0 354.1 734.0]/Border[0 0 0]/A 135 0 R>>endobj
-137 0 obj<</S/URI/URI(winbind.html)>>endobj
-138 0 obj<</Subtype/Link/Rect[153.9 668.2 222.3 681.2]/Border[0 0 0]/A 137 0 R>>endobj
-139 0 obj<</S/URI/URI(http://www.linuxworld.com)>>endobj
-140 0 obj<</Subtype/Link/Rect[443.5 351.4 500.6 364.4]/Border[0 0 0]/A 139 0 R>>endobj
-141 0 obj<</S/URI/URI(http://www.linuxworld.com/linuxworld/lw-1998-10/lw-10-samba.html)>>endobj
-142 0 obj<</Subtype/Link/Rect[72.0 338.2 189.3 351.2]/Border[0 0 0]/A 141 0 R>>endobj
-143 0 obj[136 0 R
-138 0 R
-140 0 R
-142 0 R
-]endobj
-144 0 obj<</S/URI/URI(mailto:jtrostel@snapserver.com)>>endobj
-145 0 obj<</Subtype/Link/Rect[200.6 255.4 310.1 268.4]/Border[0 0 0]/A 144 0 R>>endobj
-146 0 obj[145 0 R
-]endobj
-147 0 obj<</S/URI/URI(http://samba.org/)>>endobj
-148 0 obj<</Subtype/Link/Rect[196.9 345.8 308.1 358.8]/Border[0 0 0]/A 147 0 R>>endobj
-149 0 obj[148 0 R
-]endobj
-150 0 obj<</S/URI/URI(winbindd.8.html)>>endobj
-151 0 obj<</Subtype/Link/Rect[311.8 63.0 366.1 76.0]/Border[0 0 0]/A 150 0 R>>endobj
-152 0 obj[151 0 R
-]endobj
-153 0 obj<</S/URI/URI(#WINBINDSEPARATOR)>>endobj
-154 0 obj<</Subtype/Link/Rect[100.0 663.2 191.8 674.2]/Border[0 0 0]/A 153 0 R>>endobj
-155 0 obj<</S/URI/URI(#WINBINDUID)>>endobj
-156 0 obj<</Subtype/Link/Rect[100.0 641.6 159.4 652.6]/Border[0 0 0]/A 155 0 R>>endobj
-157 0 obj<</S/URI/URI(#WINBINDGID)>>endobj
-158 0 obj<</Subtype/Link/Rect[100.0 620.0 159.4 631.0]/Border[0 0 0]/A 157 0 R>>endobj
-159 0 obj<</S/URI/URI(#WINBINDENUMUSERS)>>endobj
-160 0 obj<</Subtype/Link/Rect[100.0 598.4 197.2 609.4]/Border[0 0 0]/A 159 0 R>>endobj
-161 0 obj<</S/URI/URI(#WINBINDENUMGROUP)>>endobj
-162 0 obj<</Subtype/Link/Rect[100.0 587.6 202.6 598.6]/Border[0 0 0]/A 161 0 R>>endobj
-163 0 obj<</S/URI/URI(#TEMPLATEHOMEDIR)>>endobj
-164 0 obj<</Subtype/Link/Rect[100.0 566.0 186.4 577.0]/Border[0 0 0]/A 163 0 R>>endobj
-165 0 obj<</S/URI/URI(#TEMPLATESHELL)>>endobj
-166 0 obj<</Subtype/Link/Rect[100.0 555.2 175.6 566.2]/Border[0 0 0]/A 165 0 R>>endobj
-167 0 obj[154 0 R
+141 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
+142 0 obj<</Subtype/Link/Rect[468.3 636.2 549.6 649.2]/Border[0 0 0]/A 141 0 R>>endobj
+143 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
+144 0 obj<</Subtype/Link/Rect[72.0 623.0 92.8 636.0]/Border[0 0 0]/A 143 0 R>>endobj
+145 0 obj<</S/URI/URI(#NETBIOSNAME)>>endobj
+146 0 obj<</Subtype/Link/Rect[94.6 549.6 159.4 560.6]/Border[0 0 0]/A 145 0 R>>endobj
+147 0 obj<</S/URI/URI(#WORKGROUP)>>endobj
+148 0 obj<</Subtype/Link/Rect[94.6 538.8 143.2 549.8]/Border[0 0 0]/A 147 0 R>>endobj
+149 0 obj<</S/URI/URI(#OSLEVEL)>>endobj
+150 0 obj<</Subtype/Link/Rect[94.6 506.4 137.8 517.4]/Border[0 0 0]/A 149 0 R>>endobj
+151 0 obj<</S/URI/URI(#PERFERREDMASTER)>>endobj
+152 0 obj<</Subtype/Link/Rect[94.6 495.6 181.0 506.6]/Border[0 0 0]/A 151 0 R>>endobj
+153 0 obj<</S/URI/URI(#DOMAINMASTER)>>endobj
+154 0 obj<</Subtype/Link/Rect[94.6 484.8 164.8 495.8]/Border[0 0 0]/A 153 0 R>>endobj
+155 0 obj<</S/URI/URI(#LOCALMASTER)>>endobj
+156 0 obj<</Subtype/Link/Rect[94.6 474.0 159.4 485.0]/Border[0 0 0]/A 155 0 R>>endobj
+157 0 obj<</S/URI/URI(#SECURITYEQUALSUSER)>>endobj
+158 0 obj<</Subtype/Link/Rect[94.6 441.6 137.8 452.6]/Border[0 0 0]/A 157 0 R>>endobj
+159 0 obj<</S/URI/URI(#ENCRYPTPASSWORDS)>>endobj
+160 0 obj<</Subtype/Link/Rect[94.6 409.2 186.4 420.2]/Border[0 0 0]/A 159 0 R>>endobj
+161 0 obj<</S/URI/URI(#DOMAINLOGONS)>>endobj
+162 0 obj<</Subtype/Link/Rect[94.6 376.8 164.8 387.8]/Border[0 0 0]/A 161 0 R>>endobj
+163 0 obj<</S/URI/URI(#LOGONPATH)>>endobj
+164 0 obj<</Subtype/Link/Rect[94.6 344.4 148.6 355.4]/Border[0 0 0]/A 163 0 R>>endobj
+165 0 obj<</S/URI/URI(#LOGONDRIVE)>>endobj
+166 0 obj<</Subtype/Link/Rect[94.6 301.2 154.0 312.2]/Border[0 0 0]/A 165 0 R>>endobj
+167 0 obj<</S/URI/URI(#LOGONHOME)>>endobj
+168 0 obj<</Subtype/Link/Rect[94.6 290.4 148.6 301.4]/Border[0 0 0]/A 167 0 R>>endobj
+169 0 obj<</S/URI/URI(#LOGONSCRIPT)>>endobj
+170 0 obj<</Subtype/Link/Rect[94.6 247.2 159.4 258.2]/Border[0 0 0]/A 169 0 R>>endobj
+171 0 obj<</S/URI/URI(#PATH)>>endobj
+172 0 obj<</Subtype/Link/Rect[94.6 204.0 116.2 215.0]/Border[0 0 0]/A 171 0 R>>endobj
+173 0 obj<</S/URI/URI(#READONLY)>>endobj
+174 0 obj<</Subtype/Link/Rect[94.6 193.2 143.2 204.2]/Border[0 0 0]/A 173 0 R>>endobj
+175 0 obj<</S/URI/URI(#WRITELIST)>>endobj
+176 0 obj<</Subtype/Link/Rect[94.6 182.4 148.6 193.4]/Border[0 0 0]/A 175 0 R>>endobj
+177 0 obj<</S/URI/URI(#PATH)>>endobj
+178 0 obj<</Subtype/Link/Rect[94.6 139.2 116.2 150.2]/Border[0 0 0]/A 177 0 R>>endobj
+179 0 obj<</S/URI/URI(#READONLY)>>endobj
+180 0 obj<</Subtype/Link/Rect[94.6 128.4 143.2 139.4]/Border[0 0 0]/A 179 0 R>>endobj
+181 0 obj<</S/URI/URI(#CREATEMASK)>>endobj
+182 0 obj<</Subtype/Link/Rect[94.6 117.6 154.0 128.6]/Border[0 0 0]/A 181 0 R>>endobj
+183 0 obj<</S/URI/URI(#DIRECTORYMASK)>>endobj
+184 0 obj<</Subtype/Link/Rect[94.6 106.8 170.2 117.8]/Border[0 0 0]/A 183 0 R>>endobj
+185 0 obj[142 0 R
+144 0 R
+146 0 R
+148 0 R
+150 0 R
+152 0 R
+154 0 R
156 0 R
158 0 R
160 0 R
162 0 R
164 0 R
166 0 R
-]endobj
-168 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
-169 0 obj<</Subtype/Link/Rect[182.3 603.4 254.9 616.4]/Border[0 0 0]/A 168 0 R>>endobj
-170 0 obj<</S/URI/URI(ENCRYPTION.html)>>endobj
-171 0 obj<</Subtype/Link/Rect[334.9 603.4 418.9 616.4]/Border[0 0 0]/A 170 0 R>>endobj
-172 0 obj<</S/URI/URI(UNIX_INSTALL.html)>>endobj
-173 0 obj<</Subtype/Link/Rect[339.0 439.4 443.5 452.4]/Border[0 0 0]/A 172 0 R>>endobj
-174 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
-175 0 obj<</Subtype/Link/Rect[445.9 426.2 544.6 439.2]/Border[0 0 0]/A 174 0 R>>endobj
-176 0 obj[169 0 R
-171 0 R
-173 0 R
-175 0 R
-]endobj
-177 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
-178 0 obj<</Subtype/Link/Rect[468.3 636.2 549.6 649.2]/Border[0 0 0]/A 177 0 R>>endobj
-179 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
-180 0 obj<</Subtype/Link/Rect[72.0 623.0 92.8 636.0]/Border[0 0 0]/A 179 0 R>>endobj
-181 0 obj<</S/URI/URI(#NETBIOSNAME)>>endobj
-182 0 obj<</Subtype/Link/Rect[94.6 549.6 159.4 560.6]/Border[0 0 0]/A 181 0 R>>endobj
-183 0 obj<</S/URI/URI(#WORKGROUP)>>endobj
-184 0 obj<</Subtype/Link/Rect[94.6 538.8 143.2 549.8]/Border[0 0 0]/A 183 0 R>>endobj
-185 0 obj<</S/URI/URI(#OSLEVEL)>>endobj
-186 0 obj<</Subtype/Link/Rect[94.6 506.4 137.8 517.4]/Border[0 0 0]/A 185 0 R>>endobj
-187 0 obj<</S/URI/URI(#PERFERREDMASTER)>>endobj
-188 0 obj<</Subtype/Link/Rect[94.6 495.6 181.0 506.6]/Border[0 0 0]/A 187 0 R>>endobj
-189 0 obj<</S/URI/URI(#DOMAINMASTER)>>endobj
-190 0 obj<</Subtype/Link/Rect[94.6 484.8 164.8 495.8]/Border[0 0 0]/A 189 0 R>>endobj
-191 0 obj<</S/URI/URI(#LOCALMASTER)>>endobj
-192 0 obj<</Subtype/Link/Rect[94.6 474.0 159.4 485.0]/Border[0 0 0]/A 191 0 R>>endobj
-193 0 obj<</S/URI/URI(#SECURITYEQUALSUSER)>>endobj
-194 0 obj<</Subtype/Link/Rect[94.6 441.6 137.8 452.6]/Border[0 0 0]/A 193 0 R>>endobj
-195 0 obj<</S/URI/URI(#ENCRYPTPASSWORDS)>>endobj
-196 0 obj<</Subtype/Link/Rect[94.6 409.2 186.4 420.2]/Border[0 0 0]/A 195 0 R>>endobj
-197 0 obj<</S/URI/URI(#DOMAINLOGONS)>>endobj
-198 0 obj<</Subtype/Link/Rect[94.6 376.8 164.8 387.8]/Border[0 0 0]/A 197 0 R>>endobj
-199 0 obj<</S/URI/URI(#LOGONPATH)>>endobj
-200 0 obj<</Subtype/Link/Rect[94.6 344.4 148.6 355.4]/Border[0 0 0]/A 199 0 R>>endobj
-201 0 obj<</S/URI/URI(#LOGONDRIVE)>>endobj
-202 0 obj<</Subtype/Link/Rect[94.6 301.2 154.0 312.2]/Border[0 0 0]/A 201 0 R>>endobj
-203 0 obj<</S/URI/URI(#LOGONHOME)>>endobj
-204 0 obj<</Subtype/Link/Rect[94.6 290.4 148.6 301.4]/Border[0 0 0]/A 203 0 R>>endobj
-205 0 obj<</S/URI/URI(#LOGONSCRIPT)>>endobj
-206 0 obj<</Subtype/Link/Rect[94.6 247.2 159.4 258.2]/Border[0 0 0]/A 205 0 R>>endobj
-207 0 obj<</S/URI/URI(#PATH)>>endobj
-208 0 obj<</Subtype/Link/Rect[94.6 204.0 116.2 215.0]/Border[0 0 0]/A 207 0 R>>endobj
-209 0 obj<</S/URI/URI(#READONLY)>>endobj
-210 0 obj<</Subtype/Link/Rect[94.6 193.2 143.2 204.2]/Border[0 0 0]/A 209 0 R>>endobj
-211 0 obj<</S/URI/URI(#WRITELIST)>>endobj
-212 0 obj<</Subtype/Link/Rect[94.6 182.4 148.6 193.4]/Border[0 0 0]/A 211 0 R>>endobj
-213 0 obj<</S/URI/URI(#PATH)>>endobj
-214 0 obj<</Subtype/Link/Rect[94.6 139.2 116.2 150.2]/Border[0 0 0]/A 213 0 R>>endobj
-215 0 obj<</S/URI/URI(#READONLY)>>endobj
-216 0 obj<</Subtype/Link/Rect[94.6 128.4 143.2 139.4]/Border[0 0 0]/A 215 0 R>>endobj
-217 0 obj<</S/URI/URI(#CREATEMASK)>>endobj
-218 0 obj<</Subtype/Link/Rect[94.6 117.6 154.0 128.6]/Border[0 0 0]/A 217 0 R>>endobj
-219 0 obj<</S/URI/URI(#DIRECTORYMASK)>>endobj
-220 0 obj<</Subtype/Link/Rect[94.6 106.8 170.2 117.8]/Border[0 0 0]/A 219 0 R>>endobj
-221 0 obj[178 0 R
+168 0 R
+170 0 R
+172 0 R
+174 0 R
+176 0 R
+178 0 R
180 0 R
182 0 R
184 0 R
-186 0 R
-188 0 R
-190 0 R
-192 0 R
-194 0 R
+]endobj
+186 0 obj<</S/URI/URI(ENCRYPTION.html)>>endobj
+187 0 obj<</Subtype/Link/Rect[108.0 707.8 200.6 720.8]/Border[0 0 0]/A 186 0 R>>endobj
+188 0 obj<</S/URI/URI(#DOMAINADMINGROUP)>>endobj
+189 0 obj<</Subtype/Link/Rect[497.0 615.4 530.0 628.4]/Border[0 0 0]/A 188 0 R>>endobj
+190 0 obj<</S/URI/URI(#DOMAINADMINGROUP)>>endobj
+191 0 obj<</Subtype/Link/Rect[72.0 602.2 127.9 615.2]/Border[0 0 0]/A 190 0 R>>endobj
+192 0 obj[187 0 R
+189 0 R
+191 0 R
+]endobj
+193 0 obj<</S/URI/URI(smbpasswd.8.html)>>endobj
+194 0 obj<</Subtype/Link/Rect[72.0 550.6 138.6 563.6]/Border[0 0 0]/A 193 0 R>>endobj
+195 0 obj<</S/URI/URI(#ADDUSERSCRIPT)>>endobj
+196 0 obj<</Subtype/Link/Rect[422.7 229.4 486.9 242.4]/Border[0 0 0]/A 195 0 R>>endobj
+197 0 obj[194 0 R
196 0 R
-198 0 R
-200 0 R
-202 0 R
+]endobj
+198 0 obj<</S/URI/URI(http://www.microsoft.com/ntserver/management/deployment/planguide/prof_policies.asp)>>endobj
+199 0 obj<</Subtype/Link/Rect[164.2 636.2 409.3 649.2]/Border[0 0 0]/A 198 0 R>>endobj
+200 0 obj[199 0 R
+]endobj
+201 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE)>>endobj
+202 0 obj<</Subtype/Link/Rect[287.9 721.0 540.0 734.0]/Border[0 0 0]/A 201 0 R>>endobj
+203 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE)>>endobj
+204 0 obj<</Subtype/Link/Rect[236.3 681.4 508.6 694.4]/Border[0 0 0]/A 203 0 R>>endobj
+205 0 obj<</S/URI/URI(http://www.tcpdump.org/)>>endobj
+206 0 obj<</Subtype/Link/Rect[352.1 266.6 458.1 279.6]/Border[0 0 0]/A 205 0 R>>endobj
+207 0 obj<</S/URI/URI(http://www.ethereal.com/)>>endobj
+208 0 obj<</Subtype/Link/Rect[430.0 253.4 539.4 266.4]/Border[0 0 0]/A 207 0 R>>endobj
+209 0 obj[202 0 R
204 0 R
206 0 R
208 0 R
-210 0 R
-212 0 R
-214 0 R
-216 0 R
-218 0 R
-220 0 R
]endobj
-222 0 obj<</S/URI/URI(ENCRYPTION.html)>>endobj
-223 0 obj<</Subtype/Link/Rect[108.0 707.8 200.6 720.8]/Border[0 0 0]/A 222 0 R>>endobj
-224 0 obj<</S/URI/URI(#DOMAINADMINGROUP)>>endobj
-225 0 obj<</Subtype/Link/Rect[497.0 615.4 530.0 628.4]/Border[0 0 0]/A 224 0 R>>endobj
-226 0 obj<</S/URI/URI(#DOMAINADMINGROUP)>>endobj
-227 0 obj<</Subtype/Link/Rect[72.0 602.2 127.9 615.2]/Border[0 0 0]/A 226 0 R>>endobj
-228 0 obj[223 0 R
+210 0 obj<</S/URI/URI(http://samba.org)>>endobj
+211 0 obj<</Subtype/Link/Rect[236.3 338.2 310.8 351.2]/Border[0 0 0]/A 210 0 R>>endobj
+212 0 obj<</S/URI/URI(http://www.skippy.net/linux/smb-howto.html)>>endobj
+213 0 obj<</Subtype/Link/Rect[144.0 285.4 346.1 298.4]/Border[0 0 0]/A 212 0 R>>endobj
+214 0 obj<</S/URI/URI(http://bioserve.latrobe.edu.au/samba)>>endobj
+215 0 obj<</Subtype/Link/Rect[182.5 259.0 345.0 272.0]/Border[0 0 0]/A 214 0 R>>endobj
+216 0 obj<</S/URI/URI(http://samba.org/cifs/)>>endobj
+217 0 obj<</Subtype/Link/Rect[284.9 245.8 381.4 258.8]/Border[0 0 0]/A 216 0 R>>endobj
+218 0 obj<</S/URI/URI(http://mailhost.cb1.com/~lkcl/ntdom/)>>endobj
+219 0 obj<</Subtype/Link/Rect[244.2 232.6 411.2 245.6]/Border[0 0 0]/A 218 0 R>>endobj
+220 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/developr/drg/CIFS/)>>endobj
+221 0 obj<</Subtype/Link/Rect[280.3 219.4 471.9 232.4]/Border[0 0 0]/A 220 0 R>>endobj
+222 0 obj<</S/URI/URI(http://samba.org)>>endobj
+223 0 obj<</Subtype/Link/Rect[361.0 166.6 432.8 179.6]/Border[0 0 0]/A 222 0 R>>endobj
+224 0 obj<</S/URI/URI(http://www.samba-tng.org/)>>endobj
+225 0 obj<</Subtype/Link/Rect[301.1 127.0 425.6 140.0]/Border[0 0 0]/A 224 0 R>>endobj
+226 0 obj[211 0 R
+213 0 R
+215 0 R
+217 0 R
+219 0 R
+221 0 R
+223 0 R
225 0 R
-227 0 R
]endobj
-229 0 obj<</S/URI/URI(smbpasswd.8.html)>>endobj
-230 0 obj<</Subtype/Link/Rect[72.0 524.2 138.6 537.2]/Border[0 0 0]/A 229 0 R>>endobj
-231 0 obj<</S/URI/URI(#ADDUSERSCRIPT)>>endobj
-232 0 obj<</Subtype/Link/Rect[422.7 203.0 486.9 216.0]/Border[0 0 0]/A 231 0 R>>endobj
-233 0 obj[230 0 R
-232 0 R
+227 0 obj<</S/URI/URI(http://lists.samba.org/)>>endobj
+228 0 obj<</Subtype/Link/Rect[135.5 351.4 227.8 364.4]/Border[0 0 0]/A 227 0 R>>endobj
+229 0 obj<</S/URI/URI(http://lists.samba.org/mailman/roster/samba-ntdom)>>endobj
+230 0 obj<</Subtype/Link/Rect[309.0 338.2 330.7 351.2]/Border[0 0 0]/A 229 0 R>>endobj
+231 0 obj[228 0 R
+230 0 R
]endobj
-234 0 obj<</S/URI/URI(http://www.microsoft.com/ntserver/management/deployment/planguide/prof_policies.asp)>>endobj
-235 0 obj<</Subtype/Link/Rect[164.2 636.2 409.3 649.2]/Border[0 0 0]/A 234 0 R>>endobj
-236 0 obj[235 0 R
+232 0 obj<</S/URI/URI(Samba-PDC-HOWTO.html)>>endobj
+233 0 obj<</Subtype/Link/Rect[213.2 616.6 317.8 629.6]/Border[0 0 0]/A 232 0 R>>endobj
+234 0 obj[233 0 R
]endobj
-237 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/Softlib/MSLFILES/NEXUS.EXE)>>endobj
-238 0 obj<</Subtype/Link/Rect[287.9 721.0 540.0 734.0]/Border[0 0 0]/A 237 0 R>>endobj
-239 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/Softlib/MSLFILES/SRVTOOLS.EXE)>>endobj
-240 0 obj<</Subtype/Link/Rect[236.3 681.4 508.6 694.4]/Border[0 0 0]/A 239 0 R>>endobj
-241 0 obj<</S/URI/URI(http://www.tcpdump.org/)>>endobj
-242 0 obj<</Subtype/Link/Rect[352.1 266.6 458.1 279.6]/Border[0 0 0]/A 241 0 R>>endobj
-243 0 obj<</S/URI/URI(http://www.ethereal.com/)>>endobj
-244 0 obj<</Subtype/Link/Rect[430.0 253.4 539.4 266.4]/Border[0 0 0]/A 243 0 R>>endobj
-245 0 obj[238 0 R
+235 0 obj<</S/URI/URI(http://www.openldap.org/)>>endobj
+236 0 obj<</Subtype/Link/Rect[172.3 563.8 285.9 576.8]/Border[0 0 0]/A 235 0 R>>endobj
+237 0 obj<</S/URI/URI(http://iplanet.netscape.com/directory)>>endobj
+238 0 obj<</Subtype/Link/Rect[226.6 550.6 387.9 563.6]/Border[0 0 0]/A 237 0 R>>endobj
+239 0 obj<</S/URI/URI(http://www.ora.com/)>>endobj
+240 0 obj<</Subtype/Link/Rect[115.4 524.2 202.0 537.2]/Border[0 0 0]/A 239 0 R>>endobj
+241 0 obj<</S/URI/URI(http://www.unav.es/cti/ldap-smb/ldap-smb-2_2-howto.html)>>endobj
+242 0 obj<</Subtype/Link/Rect[127.9 458.2 267.5 471.2]/Border[0 0 0]/A 241 0 R>>endobj
+243 0 obj<</S/URI/URI(http://samba.idealx.org/)>>endobj
+244 0 obj<</Subtype/Link/Rect[246.4 445.0 287.3 458.0]/Border[0 0 0]/A 243 0 R>>endobj
+245 0 obj<</S/URI/URI(#ENCRYPTPASSWORDS)>>endobj
+246 0 obj<</Subtype/Link/Rect[215.6 360.2 332.5 373.2]/Border[0 0 0]/A 245 0 R>>endobj
+247 0 obj[236 0 R
+238 0 R
240 0 R
242 0 R
244 0 R
+246 0 R
]endobj
-246 0 obj<</S/URI/URI(http://samba.org)>>endobj
-247 0 obj<</Subtype/Link/Rect[236.3 338.2 310.8 351.2]/Border[0 0 0]/A 246 0 R>>endobj
-248 0 obj<</S/URI/URI(http://www.skippy.net/linux/smb-howto.html)>>endobj
-249 0 obj<</Subtype/Link/Rect[144.0 285.4 346.1 298.4]/Border[0 0 0]/A 248 0 R>>endobj
-250 0 obj<</S/URI/URI(http://bioserve.latrobe.edu.au/samba)>>endobj
-251 0 obj<</Subtype/Link/Rect[182.5 259.0 345.0 272.0]/Border[0 0 0]/A 250 0 R>>endobj
-252 0 obj<</S/URI/URI(http://samba.org/cifs/)>>endobj
-253 0 obj<</Subtype/Link/Rect[284.9 245.8 381.4 258.8]/Border[0 0 0]/A 252 0 R>>endobj
-254 0 obj<</S/URI/URI(http://mailhost.cb1.com/~lkcl/ntdom/)>>endobj
-255 0 obj<</Subtype/Link/Rect[244.2 232.6 411.2 245.6]/Border[0 0 0]/A 254 0 R>>endobj
-256 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/developr/drg/CIFS/)>>endobj
-257 0 obj<</Subtype/Link/Rect[280.3 219.4 471.9 232.4]/Border[0 0 0]/A 256 0 R>>endobj
-258 0 obj<</S/URI/URI(http://samba.org)>>endobj
-259 0 obj<</Subtype/Link/Rect[361.0 166.6 432.8 179.6]/Border[0 0 0]/A 258 0 R>>endobj
-260 0 obj<</S/URI/URI(http://www.samba-tng.org/)>>endobj
-261 0 obj<</Subtype/Link/Rect[301.1 127.0 425.6 140.0]/Border[0 0 0]/A 260 0 R>>endobj
-262 0 obj[247 0 R
-249 0 R
+248 0 obj<</S/URI/URI(http://www.padl.com/)>>endobj
+249 0 obj<</Subtype/Link/Rect[284.3 589.0 380.9 602.0]/Border[0 0 0]/A 248 0 R>>endobj
+250 0 obj<</S/URI/URI(samba-patches@samba.org)>>endobj
+251 0 obj<</Subtype/Link/Rect[335.0 464.6 458.0 477.6]/Border[0 0 0]/A 250 0 R>>endobj
+252 0 obj<</S/URI/URI(jerry@samba.org)>>endobj
+253 0 obj<</Subtype/Link/Rect[479.4 464.6 555.8 477.6]/Border[0 0 0]/A 252 0 R>>endobj
+254 0 obj<</S/URI/URI(jerry@samba.org)>>endobj
+255 0 obj<</Subtype/Link/Rect[273.9 223.8 350.4 236.8]/Border[0 0 0]/A 254 0 R>>endobj
+256 0 obj[249 0 R
251 0 R
253 0 R
255 0 R
-257 0 R
-259 0 R
-261 0 R
]endobj
-263 0 obj<</S/URI/URI(http://lists.samba.org/)>>endobj
-264 0 obj<</Subtype/Link/Rect[135.5 351.4 227.8 364.4]/Border[0 0 0]/A 263 0 R>>endobj
-265 0 obj<</S/URI/URI(http://lists.samba.org/mailman/roster/samba-ntdom)>>endobj
-266 0 obj<</Subtype/Link/Rect[309.0 338.2 330.7 351.2]/Border[0 0 0]/A 265 0 R>>endobj
-267 0 obj[264 0 R
+257 0 obj<</S/URI/URI(#LDAPSSL)>>endobj
+258 0 obj<</Subtype/Link/Rect[108.0 651.4 141.3 664.4]/Border[0 0 0]/A 257 0 R>>endobj
+259 0 obj<</S/URI/URI(#LDAPSERVER)>>endobj
+260 0 obj<</Subtype/Link/Rect[108.0 638.2 156.6 651.2]/Border[0 0 0]/A 259 0 R>>endobj
+261 0 obj<</S/URI/URI(#LDAPADMINDN)>>endobj
+262 0 obj<</Subtype/Link/Rect[108.0 625.0 170.9 638.0]/Border[0 0 0]/A 261 0 R>>endobj
+263 0 obj<</S/URI/URI(#LDAPSUFFIX)>>endobj
+264 0 obj<</Subtype/Link/Rect[108.0 611.8 155.4 624.8]/Border[0 0 0]/A 263 0 R>>endobj
+265 0 obj<</S/URI/URI(#LDAPFILTER)>>endobj
+266 0 obj<</Subtype/Link/Rect[108.0 598.6 151.1 611.6]/Border[0 0 0]/A 265 0 R>>endobj
+267 0 obj<</S/URI/URI(#LDAPPORT)>>endobj
+268 0 obj<</Subtype/Link/Rect[108.0 585.4 147.4 598.4]/Border[0 0 0]/A 267 0 R>>endobj
+269 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
+270 0 obj<</Subtype/Link/Rect[189.6 559.0 243.1 572.0]/Border[0 0 0]/A 269 0 R>>endobj
+271 0 obj[258 0 R
+260 0 R
+262 0 R
+264 0 R
266 0 R
+268 0 R
+270 0 R
]endobj
-268 0 obj<</S/URI/URI(Samba-PDC-HOWTO.html)>>endobj
-269 0 obj<</Subtype/Link/Rect[213.2 616.6 317.8 629.6]/Border[0 0 0]/A 268 0 R>>endobj
-270 0 obj[269 0 R
+272 0 obj<</S/URI/URI(ENCRYPTION.html)>>endobj
+273 0 obj<</Subtype/Link/Rect[72.0 451.4 176.8 464.4]/Border[0 0 0]/A 272 0 R>>endobj
+274 0 obj[273 0 R
]endobj
-271 0 obj<</S/URI/URI(http://www.openldap.org/)>>endobj
-272 0 obj<</Subtype/Link/Rect[172.3 563.8 285.9 576.8]/Border[0 0 0]/A 271 0 R>>endobj
-273 0 obj<</S/URI/URI(http://iplanet.netscape.com/directory)>>endobj
-274 0 obj<</Subtype/Link/Rect[226.6 550.6 387.9 563.6]/Border[0 0 0]/A 273 0 R>>endobj
-275 0 obj<</S/URI/URI(http://www.ora.com/)>>endobj
-276 0 obj<</Subtype/Link/Rect[115.4 524.2 202.0 537.2]/Border[0 0 0]/A 275 0 R>>endobj
-277 0 obj<</S/URI/URI(http://www.unav.es/cti/ldap-smb/ldap-smb-2_2-howto.html)>>endobj
-278 0 obj<</Subtype/Link/Rect[127.9 458.2 267.5 471.2]/Border[0 0 0]/A 277 0 R>>endobj
-279 0 obj<</S/URI/URI(http://samba.idealx.org/)>>endobj
-280 0 obj<</Subtype/Link/Rect[246.4 445.0 287.3 458.0]/Border[0 0 0]/A 279 0 R>>endobj
-281 0 obj<</S/URI/URI(#ENCRYPTPASSWORDS)>>endobj
-282 0 obj<</Subtype/Link/Rect[215.6 360.2 332.5 373.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
+275 0 obj<</S/URI/URI(Samba-PDC-HOWTO.html)>>endobj
+276 0 obj<</Subtype/Link/Rect[72.0 391.0 176.7 404.0]/Border[0 0 0]/A 275 0 R>>endobj
+277 0 obj[276 0 R
]endobj
-284 0 obj<</S/URI/URI(http://www.padl.com/)>>endobj
-285 0 obj<</Subtype/Link/Rect[284.3 589.0 380.9 602.0]/Border[0 0 0]/A 284 0 R>>endobj
-286 0 obj<</S/URI/URI(samba-patches@samba.org)>>endobj
-287 0 obj<</Subtype/Link/Rect[335.0 464.6 458.0 477.6]/Border[0 0 0]/A 286 0 R>>endobj
-288 0 obj<</S/URI/URI(jerry@samba.org)>>endobj
-289 0 obj<</Subtype/Link/Rect[479.4 464.6 555.8 477.6]/Border[0 0 0]/A 288 0 R>>endobj
-290 0 obj<</S/URI/URI(jerry@samba.org)>>endobj
-291 0 obj<</Subtype/Link/Rect[273.9 223.8 350.4 236.8]/Border[0 0 0]/A 290 0 R>>endobj
-292 0 obj[285 0 R
-287 0 R
-289 0 R
-291 0 R
+278 0 obj<</S/URI/URI(mailto:jerry@samba.org)>>endobj
+279 0 obj<</Subtype/Link/Rect[305.4 285.8 381.8 298.8]/Border[0 0 0]/A 278 0 R>>endobj
+280 0 obj[279 0 R
]endobj
-293 0 obj<</S/URI/URI(#LDAPSSL)>>endobj
-294 0 obj<</Subtype/Link/Rect[108.0 651.4 141.3 664.4]/Border[0 0 0]/A 293 0 R>>endobj
-295 0 obj<</S/URI/URI(#LDAPSERVER)>>endobj
-296 0 obj<</Subtype/Link/Rect[108.0 638.2 156.6 651.2]/Border[0 0 0]/A 295 0 R>>endobj
-297 0 obj<</S/URI/URI(#LDAPADMINDN)>>endobj
-298 0 obj<</Subtype/Link/Rect[108.0 625.0 170.9 638.0]/Border[0 0 0]/A 297 0 R>>endobj
-299 0 obj<</S/URI/URI(#LDAPSUFFIX)>>endobj
-300 0 obj<</Subtype/Link/Rect[108.0 611.8 155.4 624.8]/Border[0 0 0]/A 299 0 R>>endobj
-301 0 obj<</S/URI/URI(#LDAPFILTER)>>endobj
-302 0 obj<</Subtype/Link/Rect[108.0 598.6 151.1 611.6]/Border[0 0 0]/A 301 0 R>>endobj
-303 0 obj<</S/URI/URI(#LDAPPORT)>>endobj
-304 0 obj<</Subtype/Link/Rect[108.0 585.4 147.4 598.4]/Border[0 0 0]/A 303 0 R>>endobj
-305 0 obj<</S/URI/URI(smb.conf.5.html)>>endobj
-306 0 obj<</Subtype/Link/Rect[189.6 559.0 243.1 572.0]/Border[0 0 0]/A 305 0 R>>endobj
-307 0 obj[294 0 R
+281 0 obj<</S/URI/URI(mailto:jtrostel@snapserver.com)>>endobj
+282 0 obj<</Subtype/Link/Rect[200.6 255.4 310.1 268.4]/Border[0 0 0]/A 281 0 R>>endobj
+283 0 obj[282 0 R
+]endobj
+284 0 obj<</S/URI/URI(http://samba.org/)>>endobj
+285 0 obj<</Subtype/Link/Rect[196.9 385.4 308.1 398.4]/Border[0 0 0]/A 284 0 R>>endobj
+286 0 obj[285 0 R
+]endobj
+287 0 obj<</S/URI/URI(winbindd.8.html)>>endobj
+288 0 obj<</Subtype/Link/Rect[311.8 208.2 366.1 221.2]/Border[0 0 0]/A 287 0 R>>endobj
+289 0 obj<</S/URI/URI(#WINBINDSEPARATOR)>>endobj
+290 0 obj<</Subtype/Link/Rect[100.0 137.2 191.8 148.2]/Border[0 0 0]/A 289 0 R>>endobj
+291 0 obj<</S/URI/URI(#WINBINDUID)>>endobj
+292 0 obj<</Subtype/Link/Rect[100.0 115.6 159.4 126.6]/Border[0 0 0]/A 291 0 R>>endobj
+293 0 obj<</S/URI/URI(#WINBINDGID)>>endobj
+294 0 obj<</Subtype/Link/Rect[100.0 94.0 159.4 105.0]/Border[0 0 0]/A 293 0 R>>endobj
+295 0 obj<</S/URI/URI(#WINBINDENUMUSERS)>>endobj
+296 0 obj<</Subtype/Link/Rect[100.0 72.4 197.2 83.4]/Border[0 0 0]/A 295 0 R>>endobj
+297 0 obj<</S/URI/URI(#WINBINDENUMGROUP)>>endobj
+298 0 obj<</Subtype/Link/Rect[100.0 61.6 202.6 72.6]/Border[0 0 0]/A 297 0 R>>endobj
+299 0 obj[288 0 R
+290 0 R
+292 0 R
+294 0 R
296 0 R
298 0 R
-300 0 R
-302 0 R
-304 0 R
-306 0 R
]endobj
-308 0 obj<</S/URI/URI(ENCRYPTION.html)>>endobj
-309 0 obj<</Subtype/Link/Rect[72.0 451.4 176.8 464.4]/Border[0 0 0]/A 308 0 R>>endobj
-310 0 obj[309 0 R
+300 0 obj<</S/URI/URI(#TEMPLATEHOMEDIR)>>endobj
+301 0 obj<</Subtype/Link/Rect[100.0 711.2 186.4 722.2]/Border[0 0 0]/A 300 0 R>>endobj
+302 0 obj<</S/URI/URI(#TEMPLATESHELL)>>endobj
+303 0 obj<</Subtype/Link/Rect[100.0 700.4 175.6 711.4]/Border[0 0 0]/A 302 0 R>>endobj
+304 0 obj[301 0 R
+303 0 R
]endobj
-311 0 obj<</S/URI/URI(Samba-PDC-HOWTO.html)>>endobj
-312 0 obj<</Subtype/Link/Rect[72.0 391.0 176.7 404.0]/Border[0 0 0]/A 311 0 R>>endobj
-313 0 obj[312 0 R
+305 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/samba/warp.html)>>endobj
+306 0 obj<</Subtype/Link/Rect[331.1 607.0 550.0 620.0]/Border[0 0 0]/A 305 0 R>>endobj
+307 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/)>>endobj
+308 0 obj<</Subtype/Link/Rect[72.0 241.4 319.2 254.4]/Border[0 0 0]/A 307 0 R>>endobj
+309 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/lanman.html)>>endobj
+310 0 obj<</Subtype/Link/Rect[346.1 241.4 544.2 254.4]/Border[0 0 0]/A 309 0 R>>endobj
+311 0 obj<</S/URI/URI(ftp://ftp.cdrom.com/pub/os2/network/ndis/)>>endobj
+312 0 obj<</Subtype/Link/Rect[175.9 117.8 366.2 130.8]/Border[0 0 0]/A 311 0 R>>endobj
+313 0 obj[306 0 R
+308 0 R
+310 0 R
+312 0 R
]endobj
-314 0 obj<</S/URI/URI(mailto:jerry@samba.org)>>endobj
-315 0 obj<</Subtype/Link/Rect[305.4 285.8 381.8 298.8]/Border[0 0 0]/A 314 0 R>>endobj
+314 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/samba/fix.html)>>endobj
+315 0 obj<</Subtype/Link/Rect[225.7 661.0 434.8 674.0]/Border[0 0 0]/A 314 0 R>>endobj
316 0 obj[315 0 R
]endobj
-317 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/samba/warp.html)>>endobj
-318 0 obj<</Subtype/Link/Rect[331.1 607.0 550.0 620.0]/Border[0 0 0]/A 317 0 R>>endobj
-319 0 obj<</S/URI/URI(ftp://ftp.microsoft.com/BusSys/Clients/LANMAN.OS2/)>>endobj
-320 0 obj<</Subtype/Link/Rect[72.0 241.4 319.2 254.4]/Border[0 0 0]/A 319 0 R>>endobj
-321 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/lanman.html)>>endobj
-322 0 obj<</Subtype/Link/Rect[346.1 241.4 544.2 254.4]/Border[0 0 0]/A 321 0 R>>endobj
-323 0 obj<</S/URI/URI(ftp://ftp.cdrom.com/pub/os2/network/ndis/)>>endobj
-324 0 obj<</Subtype/Link/Rect[175.9 117.8 366.2 130.8]/Border[0 0 0]/A 323 0 R>>endobj
-325 0 obj[318 0 R
+317 0 obj<</S/URI/URI(http://samba.org/samba/cvs.html)>>endobj
+318 0 obj<</Subtype/Link/Rect[357.1 577.0 500.7 590.0]/Border[0 0 0]/A 317 0 R>>endobj
+319 0 obj<</S/URI/URI(http://samba.org/cgi-bin/cvsweb)>>endobj
+320 0 obj<</Subtype/Link/Rect[138.6 354.6 283.2 367.6]/Border[0 0 0]/A 319 0 R>>endobj
+321 0 obj<</S/URI/URI(http://www.cyclic.com/)>>endobj
+322 0 obj<</Subtype/Link/Rect[394.3 230.2 498.2 243.2]/Border[0 0 0]/A 321 0 R>>endobj
+323 0 obj[318 0 R
320 0 R
322 0 R
-324 0 R
]endobj
-326 0 obj<</S/URI/URI(http://carol.wins.uva.nl/~leeuw/samba/fix.html)>>endobj
-327 0 obj<</Subtype/Link/Rect[225.7 661.0 434.8 674.0]/Border[0 0 0]/A 326 0 R>>endobj
-328 0 obj[327 0 R
+324 0 obj<</S/URI/URI(x1100.htm)>>endobj
+325 0 obj<</Subtype/Link/Rect[201.6 408.2 258.1 421.2]/Border[0 0 0]/A 324 0 R>>endobj
+326 0 obj[325 0 R
]endobj
-329 0 obj<</S/URI/URI(http://samba.org/samba/cvs.html)>>endobj
-330 0 obj<</Subtype/Link/Rect[357.1 577.0 500.7 590.0]/Border[0 0 0]/A 329 0 R>>endobj
-331 0 obj<</S/URI/URI(http://samba.org/cgi-bin/cvsweb)>>endobj
-332 0 obj<</Subtype/Link/Rect[138.6 354.6 283.2 367.6]/Border[0 0 0]/A 331 0 R>>endobj
-333 0 obj<</S/URI/URI(http://www.cyclic.com/)>>endobj
-334 0 obj<</Subtype/Link/Rect[394.3 230.2 498.2 243.2]/Border[0 0 0]/A 333 0 R>>endobj
-335 0 obj[330 0 R
+327 0 obj<</Subtype/Link/Rect[72.0 684.0 277.3 697.0]/Border[0 0 0]/Dest[639 0 R/XYZ null 798 0]>>endobj
+328 0 obj<</Subtype/Link/Rect[108.0 670.8 249.2 683.8]/Border[0 0 0]/Dest[639 0 R/XYZ null 730 0]>>endobj
+329 0 obj<</Subtype/Link/Rect[108.0 657.6 255.0 670.6]/Border[0 0 0]/Dest[639 0 R/XYZ null 593 0]>>endobj
+330 0 obj<</Subtype/Link/Rect[108.0 644.4 257.7 657.4]/Border[0 0 0]/Dest[639 0 R/XYZ null 178 0]>>endobj
+331 0 obj<</Subtype/Link/Rect[108.0 631.2 309.0 644.2]/Border[0 0 0]/Dest[642 0 R/XYZ null 739 0]>>endobj
+332 0 obj<</Subtype/Link/Rect[108.0 618.0 316.7 631.0]/Border[0 0 0]/Dest[642 0 R/XYZ null 379 0]>>endobj
+333 0 obj<</Subtype/Link/Rect[108.0 604.8 284.9 617.8]/Border[0 0 0]/Dest[642 0 R/XYZ null 268 0]>>endobj
+334 0 obj<</Subtype/Link/Rect[108.0 591.6 280.0 604.6]/Border[0 0 0]/Dest[645 0 R/XYZ null 768 0]>>endobj
+335 0 obj<</Subtype/Link/Rect[108.0 578.4 328.6 591.4]/Border[0 0 0]/Dest[645 0 R/XYZ null 266 0]>>endobj
+336 0 obj<</Subtype/Link/Rect[108.0 565.2 364.9 578.2]/Border[0 0 0]/Dest[648 0 R/XYZ null 686 0]>>endobj
+337 0 obj<</Subtype/Link/Rect[108.0 552.0 315.8 565.0]/Border[0 0 0]/Dest[648 0 R/XYZ null 509 0]>>endobj
+338 0 obj<</Subtype/Link/Rect[108.0 538.8 514.3 551.8]/Border[0 0 0]/Dest[648 0 R/XYZ null 332 0]>>endobj
+339 0 obj<</Subtype/Link/Rect[108.0 525.6 259.4 538.6]/Border[0 0 0]/Dest[651 0 R/XYZ null 768 0]>>endobj
+340 0 obj<</Subtype/Link/Rect[108.0 512.4 236.0 525.4]/Border[0 0 0]/Dest[651 0 R/XYZ null 577 0]>>endobj
+341 0 obj<</Subtype/Link/Rect[108.0 499.2 186.5 512.2]/Border[0 0 0]/Dest[651 0 R/XYZ null 505 0]>>endobj
+342 0 obj<</Subtype/Link/Rect[108.0 486.0 267.2 499.0]/Border[0 0 0]/Dest[651 0 R/XYZ null 394 0]>>endobj
+343 0 obj<</Subtype/Link/Rect[108.0 472.8 295.6 485.8]/Border[0 0 0]/Dest[654 0 R/XYZ null 739 0]>>endobj
+344 0 obj<</Subtype/Link/Rect[108.0 459.6 177.7 472.6]/Border[0 0 0]/Dest[654 0 R/XYZ null 615 0]>>endobj
+345 0 obj<</Subtype/Link/Rect[108.0 446.4 232.3 459.4]/Border[0 0 0]/Dest[657 0 R/XYZ null 768 0]>>endobj
+346 0 obj<</Subtype/Link/Rect[108.0 433.2 232.6 446.2]/Border[0 0 0]/Dest[657 0 R/XYZ null 683 0]>>endobj
+347 0 obj<</Subtype/Link/Rect[72.0 406.8 348.8 419.8]/Border[0 0 0]/Dest[660 0 R/XYZ null 798 0]>>endobj
+348 0 obj<</Subtype/Link/Rect[108.0 393.6 161.5 406.6]/Border[0 0 0]/Dest[660 0 R/XYZ null 706 0]>>endobj
+349 0 obj<</Subtype/Link/Rect[108.0 380.4 327.7 393.4]/Border[0 0 0]/Dest[660 0 R/XYZ null 463 0]>>endobj
+350 0 obj<</Subtype/Link/Rect[108.0 367.2 177.1 380.2]/Border[0 0 0]/Dest[660 0 R/XYZ null 325 0]>>endobj
+351 0 obj<</Subtype/Link/Rect[108.0 354.0 203.6 367.0]/Border[0 0 0]/Dest[663 0 R/XYZ null 435 0]>>endobj
+352 0 obj<</Subtype/Link/Rect[108.0 340.8 195.1 353.8]/Border[0 0 0]/Dest[663 0 R/XYZ null 285 0]>>endobj
+353 0 obj<</Subtype/Link/Rect[108.0 327.6 215.2 340.6]/Border[0 0 0]/Dest[666 0 R/XYZ null 768 0]>>endobj
+354 0 obj<</Subtype/Link/Rect[108.0 314.4 382.4 327.4]/Border[0 0 0]/Dest[666 0 R/XYZ null 268 0]>>endobj
+355 0 obj<</Subtype/Link/Rect[108.0 301.2 255.6 314.2]/Border[0 0 0]/Dest[669 0 R/XYZ null 210 0]>>endobj
+356 0 obj<</Subtype/Link/Rect[108.0 288.0 224.1 301.0]/Border[0 0 0]/Dest[672 0 R/XYZ null 660 0]>>endobj
+357 0 obj<</Subtype/Link/Rect[108.0 274.8 187.8 287.8]/Border[0 0 0]/Dest[675 0 R/XYZ null 371 0]>>endobj
+358 0 obj<</Subtype/Link/Rect[108.0 261.6 194.5 274.6]/Border[0 0 0]/Dest[675 0 R/XYZ null 260 0]>>endobj
+359 0 obj<</Subtype/Link/Rect[108.0 248.4 200.6 261.4]/Border[0 0 0]/Dest[678 0 R/XYZ null 768 0]>>endobj
+360 0 obj<</Subtype/Link/Rect[108.0 235.2 526.0 248.2]/Border[0 0 0]/Dest[678 0 R/XYZ null 529 0]>>endobj
+361 0 obj<</Subtype/Link/Rect[108.0 222.0 500.6 235.0]/Border[0 0 0]/Dest[681 0 R/XYZ null 633 0]>>endobj
+362 0 obj<</Subtype/Link/Rect[108.0 208.8 353.3 221.8]/Border[0 0 0]/Dest[684 0 R/XYZ null 581 0]>>endobj
+363 0 obj<</Subtype/Link/Rect[108.0 195.6 419.0 208.6]/Border[0 0 0]/Dest[684 0 R/XYZ null 304 0]>>endobj
+364 0 obj<</Subtype/Link/Rect[108.0 182.4 332.5 195.4]/Border[0 0 0]/Dest[687 0 R/XYZ null 594 0]>>endobj
+365 0 obj<</Subtype/Link/Rect[108.0 169.2 181.6 182.2]/Border[0 0 0]/Dest[690 0 R/XYZ null 639 0]>>endobj
+366 0 obj<</Subtype/Link/Rect[72.0 142.8 463.4 155.8]/Border[0 0 0]/Dest[693 0 R/XYZ null 798 0]>>endobj
+367 0 obj<</Subtype/Link/Rect[108.0 129.6 202.4 142.6]/Border[0 0 0]/Dest[693 0 R/XYZ null 706 0]>>endobj
+368 0 obj<</Subtype/Link/Rect[108.0 116.4 244.9 129.4]/Border[0 0 0]/Dest[696 0 R/XYZ null 179 0]>>endobj
+369 0 obj<</Subtype/Link/Rect[108.0 103.2 270.3 116.2]/Border[0 0 0]/Dest[699 0 R/XYZ null 726 0]>>endobj
+370 0 obj<</Subtype/Link/Rect[72.0 76.8 402.3 89.8]/Border[0 0 0]/Dest[702 0 R/XYZ null 798 0]>>endobj
+371 0 obj<</Subtype/Link/Rect[108.0 63.6 179.2 76.6]/Border[0 0 0]/Dest[702 0 R/XYZ null 706 0]>>endobj
+372 0 obj[327 0 R
+328 0 R
+329 0 R
+330 0 R
+331 0 R
332 0 R
+333 0 R
334 0 R
-]endobj
-336 0 obj<</S/URI/URI(Diagnosis.html)>>endobj
-337 0 obj<</Subtype/Link/Rect[187.8 344.6 229.3 357.6]/Border[0 0 0]/A 336 0 R>>endobj
-338 0 obj[337 0 R
-]endobj
-339 0 obj<</S/URI/URI(x1741.htm)>>endobj
-340 0 obj<</Subtype/Link/Rect[201.6 645.8 258.1 658.8]/Border[0 0 0]/A 339 0 R>>endobj
-341 0 obj[340 0 R
-]endobj
-342 0 obj<</Subtype/Link/Rect[72.0 684.0 277.3 697.0]/Border[0 0 0]/Dest[798 0 R/XYZ null 798 0]>>endobj
-343 0 obj<</Subtype/Link/Rect[108.0 670.8 249.2 683.8]/Border[0 0 0]/Dest[798 0 R/XYZ null 730 0]>>endobj
-344 0 obj<</Subtype/Link/Rect[108.0 657.6 255.0 670.6]/Border[0 0 0]/Dest[798 0 R/XYZ null 593 0]>>endobj
-345 0 obj<</Subtype/Link/Rect[108.0 644.4 257.7 657.4]/Border[0 0 0]/Dest[798 0 R/XYZ null 178 0]>>endobj
-346 0 obj<</Subtype/Link/Rect[108.0 631.2 309.0 644.2]/Border[0 0 0]/Dest[801 0 R/XYZ null 739 0]>>endobj
-347 0 obj<</Subtype/Link/Rect[108.0 618.0 316.7 631.0]/Border[0 0 0]/Dest[801 0 R/XYZ null 379 0]>>endobj
-348 0 obj<</Subtype/Link/Rect[108.0 604.8 284.9 617.8]/Border[0 0 0]/Dest[801 0 R/XYZ null 268 0]>>endobj
-349 0 obj<</Subtype/Link/Rect[108.0 591.6 280.0 604.6]/Border[0 0 0]/Dest[804 0 R/XYZ null 768 0]>>endobj
-350 0 obj<</Subtype/Link/Rect[108.0 578.4 328.6 591.4]/Border[0 0 0]/Dest[804 0 R/XYZ null 266 0]>>endobj
-351 0 obj<</Subtype/Link/Rect[108.0 565.2 364.9 578.2]/Border[0 0 0]/Dest[807 0 R/XYZ null 686 0]>>endobj
-352 0 obj<</Subtype/Link/Rect[108.0 552.0 315.8 565.0]/Border[0 0 0]/Dest[807 0 R/XYZ null 509 0]>>endobj
-353 0 obj<</Subtype/Link/Rect[108.0 538.8 514.3 551.8]/Border[0 0 0]/Dest[807 0 R/XYZ null 332 0]>>endobj
-354 0 obj<</Subtype/Link/Rect[108.0 525.6 259.4 538.6]/Border[0 0 0]/Dest[810 0 R/XYZ null 768 0]>>endobj
-355 0 obj<</Subtype/Link/Rect[108.0 512.4 236.0 525.4]/Border[0 0 0]/Dest[810 0 R/XYZ null 577 0]>>endobj
-356 0 obj<</Subtype/Link/Rect[108.0 499.2 186.5 512.2]/Border[0 0 0]/Dest[810 0 R/XYZ null 505 0]>>endobj
-357 0 obj<</Subtype/Link/Rect[108.0 486.0 267.2 499.0]/Border[0 0 0]/Dest[810 0 R/XYZ null 407 0]>>endobj
-358 0 obj<</Subtype/Link/Rect[108.0 472.8 295.6 485.8]/Border[0 0 0]/Dest[813 0 R/XYZ null 768 0]>>endobj
-359 0 obj<</Subtype/Link/Rect[108.0 459.6 177.7 472.6]/Border[0 0 0]/Dest[813 0 R/XYZ null 643 0]>>endobj
-360 0 obj<</Subtype/Link/Rect[108.0 446.4 232.3 459.4]/Border[0 0 0]/Dest[813 0 R/XYZ null 175 0]>>endobj
-361 0 obj<</Subtype/Link/Rect[72.0 420.0 267.5 433.0]/Border[0 0 0]/Dest[816 0 R/XYZ null 798 0]>>endobj
-362 0 obj<</Subtype/Link/Rect[108.0 406.8 181.6 419.8]/Border[0 0 0]/Dest[816 0 R/XYZ null 730 0]>>endobj
-363 0 obj<</Subtype/Link/Rect[108.0 393.6 184.7 406.6]/Border[0 0 0]/Dest[816 0 R/XYZ null 553 0]>>endobj
-364 0 obj<</Subtype/Link/Rect[108.0 380.4 150.5 393.4]/Border[0 0 0]/Dest[816 0 R/XYZ null 186 0]>>endobj
-365 0 obj<</Subtype/Link/Rect[108.0 367.2 162.7 380.2]/Border[0 0 0]/Dest[816 0 R/XYZ null 156 0]>>endobj
-366 0 obj<</Subtype/Link/Rect[108.0 354.0 162.7 367.0]/Border[0 0 0]/Dest[819 0 R/XYZ null 726 0]>>endobj
-367 0 obj<</Subtype/Link/Rect[108.0 340.8 162.7 353.8]/Border[0 0 0]/Dest[819 0 R/XYZ null 509 0]>>endobj
-368 0 obj<</Subtype/Link/Rect[108.0 327.6 162.7 340.6]/Border[0 0 0]/Dest[822 0 R/XYZ null 581 0]>>endobj
-369 0 obj<</Subtype/Link/Rect[108.0 314.4 162.7 327.4]/Border[0 0 0]/Dest[822 0 R/XYZ null 417 0]>>endobj
-370 0 obj<</Subtype/Link/Rect[108.0 301.2 162.7 314.2]/Border[0 0 0]/Dest[822 0 R/XYZ null 279 0]>>endobj
-371 0 obj<</Subtype/Link/Rect[108.0 288.0 162.7 301.0]/Border[0 0 0]/Dest[825 0 R/XYZ null 673 0]>>endobj
-372 0 obj<</Subtype/Link/Rect[108.0 274.8 162.7 287.8]/Border[0 0 0]/Dest[825 0 R/XYZ null 298 0]>>endobj
-373 0 obj<</Subtype/Link/Rect[108.0 261.6 162.7 274.6]/Border[0 0 0]/Dest[828 0 R/XYZ null 607 0]>>endobj
-374 0 obj<</Subtype/Link/Rect[108.0 248.4 173.7 261.4]/Border[0 0 0]/Dest[828 0 R/XYZ null 430 0]>>endobj
-375 0 obj<</Subtype/Link/Rect[108.0 235.2 173.7 248.2]/Border[0 0 0]/Dest[828 0 R/XYZ null 279 0]>>endobj
-376 0 obj<</Subtype/Link/Rect[108.0 222.0 221.4 235.0]/Border[0 0 0]/Dest[831 0 R/XYZ null 768 0]>>endobj
-377 0 obj<</Subtype/Link/Rect[72.0 195.6 348.8 208.6]/Border[0 0 0]/Dest[834 0 R/XYZ null 798 0]>>endobj
-378 0 obj<</Subtype/Link/Rect[108.0 182.4 161.5 195.4]/Border[0 0 0]/Dest[834 0 R/XYZ null 706 0]>>endobj
-379 0 obj<</Subtype/Link/Rect[108.0 169.2 327.7 182.2]/Border[0 0 0]/Dest[834 0 R/XYZ null 463 0]>>endobj
-380 0 obj<</Subtype/Link/Rect[108.0 156.0 177.1 169.0]/Border[0 0 0]/Dest[834 0 R/XYZ null 325 0]>>endobj
-381 0 obj<</Subtype/Link/Rect[108.0 142.8 203.6 155.8]/Border[0 0 0]/Dest[837 0 R/XYZ null 435 0]>>endobj
-382 0 obj<</Subtype/Link/Rect[108.0 129.6 195.1 142.6]/Border[0 0 0]/Dest[837 0 R/XYZ null 285 0]>>endobj
-383 0 obj<</Subtype/Link/Rect[108.0 116.4 215.2 129.4]/Border[0 0 0]/Dest[840 0 R/XYZ null 768 0]>>endobj
-384 0 obj<</Subtype/Link/Rect[108.0 103.2 382.4 116.2]/Border[0 0 0]/Dest[840 0 R/XYZ null 268 0]>>endobj
-385 0 obj<</Subtype/Link/Rect[108.0 90.0 255.6 103.0]/Border[0 0 0]/Dest[843 0 R/XYZ null 210 0]>>endobj
-386 0 obj<</Subtype/Link/Rect[108.0 76.8 224.1 89.8]/Border[0 0 0]/Dest[846 0 R/XYZ null 660 0]>>endobj
-387 0 obj<</Subtype/Link/Rect[108.0 63.6 187.8 76.6]/Border[0 0 0]/Dest[849 0 R/XYZ null 371 0]>>endobj
-388 0 obj[342 0 R
+335 0 R
+336 0 R
+337 0 R
+338 0 R
+339 0 R
+340 0 R
+341 0 R
+342 0 R
343 0 R
344 0 R
345 0 R
@@ -560,8 +553,52 @@
369 0 R
370 0 R
371 0 R
-372 0 R
-373 0 R
+]endobj
+373 0 obj<</Subtype/Link/Rect[108.0 684.0 161.2 697.0]/Border[0 0 0]/Dest[705 0 R/XYZ null 673 0]>>endobj
+374 0 obj<</Subtype/Link/Rect[72.0 657.6 412.7 670.6]/Border[0 0 0]/Dest[708 0 R/XYZ null 798 0]>>endobj
+375 0 obj<</Subtype/Link/Rect[108.0 644.4 447.4 657.4]/Border[0 0 0]/Dest[708 0 R/XYZ null 706 0]>>endobj
+376 0 obj<</Subtype/Link/Rect[108.0 631.2 319.1 644.2]/Border[0 0 0]/Dest[708 0 R/XYZ null 525 0]>>endobj
+377 0 obj<</Subtype/Link/Rect[108.0 618.0 231.1 631.0]/Border[0 0 0]/Dest[708 0 R/XYZ null 348 0]>>endobj
+378 0 obj<</Subtype/Link/Rect[108.0 604.8 292.2 617.8]/Border[0 0 0]/Dest[711 0 R/XYZ null 686 0]>>endobj
+379 0 obj<</Subtype/Link/Rect[108.0 591.6 208.5 604.6]/Border[0 0 0]/Dest[711 0 R/XYZ null 443 0]>>endobj
+380 0 obj<</Subtype/Link/Rect[108.0 578.4 233.6 591.4]/Border[0 0 0]/Dest[711 0 R/XYZ null 187 0]>>endobj
+381 0 obj<</Subtype/Link/Rect[108.0 565.2 301.4 578.2]/Border[0 0 0]/Dest[714 0 R/XYZ null 673 0]>>endobj
+382 0 obj<</Subtype/Link/Rect[108.0 552.0 394.8 565.0]/Border[0 0 0]/Dest[714 0 R/XYZ null 232 0]>>endobj
+383 0 obj<</Subtype/Link/Rect[108.0 538.8 386.9 551.8]/Border[0 0 0]/Dest[720 0 R/XYZ null 594 0]>>endobj
+384 0 obj<</Subtype/Link/Rect[72.0 512.4 277.1 525.4]/Border[0 0 0]/Dest[723 0 R/XYZ null 798 0]>>endobj
+385 0 obj<</Subtype/Link/Rect[108.0 499.2 181.6 512.2]/Border[0 0 0]/Dest[723 0 R/XYZ null 730 0]>>endobj
+386 0 obj<</Subtype/Link/Rect[108.0 486.0 189.0 499.0]/Border[0 0 0]/Dest[723 0 R/XYZ null 302 0]>>endobj
+387 0 obj<</Subtype/Link/Rect[108.0 472.8 209.7 485.8]/Border[0 0 0]/Dest[726 0 R/XYZ null 693 0]>>endobj
+388 0 obj<</Subtype/Link/Rect[108.0 459.6 294.4 472.6]/Border[0 0 0]/Dest[729 0 R/XYZ null 450 0]>>endobj
+389 0 obj<</Subtype/Link/Rect[108.0 446.4 287.3 459.4]/Border[0 0 0]/Dest[732 0 R/XYZ null 686 0]>>endobj
+390 0 obj<</Subtype/Link/Rect[108.0 433.2 350.9 446.2]/Border[0 0 0]/Dest[732 0 R/XYZ null 302 0]>>endobj
+391 0 obj<</Subtype/Link/Rect[108.0 420.0 242.1 433.0]/Border[0 0 0]/Dest[735 0 R/XYZ null 686 0]>>endobj
+392 0 obj<</Subtype/Link/Rect[108.0 406.8 220.1 419.8]/Border[0 0 0]/Dest[735 0 R/XYZ null 496 0]>>endobj
+393 0 obj<</Subtype/Link/Rect[108.0 393.6 214.3 406.6]/Border[0 0 0]/Dest[735 0 R/XYZ null 385 0]>>endobj
+394 0 obj<</Subtype/Link/Rect[108.0 380.4 281.2 393.4]/Border[0 0 0]/Dest[735 0 R/XYZ null 247 0]>>endobj
+395 0 obj<</Subtype/Link/Rect[108.0 367.2 222.3 380.2]/Border[0 0 0]/Dest[735 0 R/XYZ null 149 0]>>endobj
+396 0 obj<</Subtype/Link/Rect[108.0 354.0 234.5 367.0]/Border[0 0 0]/Dest[738 0 R/XYZ null 713 0]>>endobj
+397 0 obj<</Subtype/Link/Rect[108.0 340.8 300.2 353.8]/Border[0 0 0]/Dest[741 0 R/XYZ null 768 0]>>endobj
+398 0 obj<</Subtype/Link/Rect[72.0 314.4 272.9 327.4]/Border[0 0 0]/Dest[744 0 R/XYZ null 798 0]>>endobj
+399 0 obj<</Subtype/Link/Rect[108.0 301.2 299.9 314.2]/Border[0 0 0]/Dest[744 0 R/XYZ null 730 0]>>endobj
+400 0 obj<</Subtype/Link/Rect[108.0 288.0 288.0 301.0]/Border[0 0 0]/Dest[747 0 R/XYZ null 383 0]>>endobj
+401 0 obj<</Subtype/Link/Rect[108.0 274.8 307.9 287.8]/Border[0 0 0]/Dest[747 0 R/XYZ null 166 0]>>endobj
+402 0 obj<</Subtype/Link/Rect[72.0 248.4 416.3 261.4]/Border[0 0 0]/Dest[753 0 R/XYZ null 798 0]>>endobj
+403 0 obj<</Subtype/Link/Rect[108.0 235.2 219.2 248.2]/Border[0 0 0]/Dest[753 0 R/XYZ null 706 0]>>endobj
+404 0 obj<</Subtype/Link/Rect[108.0 222.0 181.0 235.0]/Border[0 0 0]/Dest[753 0 R/XYZ null 608 0]>>endobj
+405 0 obj<</Subtype/Link/Rect[108.0 208.8 316.1 221.8]/Border[0 0 0]/Dest[756 0 R/XYZ null 726 0]>>endobj
+406 0 obj<</Subtype/Link/Rect[108.0 195.6 430.0 208.6]/Border[0 0 0]/Dest[759 0 R/XYZ null 607 0]>>endobj
+407 0 obj<</Subtype/Link/Rect[108.0 182.4 333.2 195.4]/Border[0 0 0]/Dest[759 0 R/XYZ null 232 0]>>endobj
+408 0 obj<</Subtype/Link/Rect[108.0 169.2 362.5 182.2]/Border[0 0 0]/Dest[762 0 R/XYZ null 359 0]>>endobj
+409 0 obj<</Subtype/Link/Rect[108.0 156.0 279.4 169.0]/Border[0 0 0]/Dest[765 0 R/XYZ null 768 0]>>endobj
+410 0 obj<</Subtype/Link/Rect[108.0 142.8 261.4 155.8]/Border[0 0 0]/Dest[765 0 R/XYZ null 392 0]>>endobj
+411 0 obj<</Subtype/Link/Rect[108.0 129.6 252.8 142.6]/Border[0 0 0]/Dest[771 0 R/XYZ null 739 0]>>endobj
+412 0 obj<</Subtype/Link/Rect[108.0 116.4 243.6 129.4]/Border[0 0 0]/Dest[774 0 R/XYZ null 686 0]>>endobj
+413 0 obj<</Subtype/Link/Rect[108.0 103.2 292.9 116.2]/Border[0 0 0]/Dest[780 0 R/XYZ null 303 0]>>endobj
+414 0 obj<</Subtype/Link/Rect[108.0 90.0 332.0 103.0]/Border[0 0 0]/Dest[783 0 R/XYZ null 277 0]>>endobj
+415 0 obj<</Subtype/Link/Rect[108.0 76.8 406.2 89.8]/Border[0 0 0]/Dest[786 0 R/XYZ null 482 0]>>endobj
+416 0 obj<</Subtype/Link/Rect[108.0 63.6 431.0 76.6]/Border[0 0 0]/Dest[798 0 R/XYZ null 274 0]>>endobj
+417 0 obj[373 0 R
374 0 R
375 0 R
376 0 R
@@ -576,51 +613,8 @@
385 0 R
386 0 R
387 0 R
-]endobj
-389 0 obj<</Subtype/Link/Rect[108.0 684.0 194.5 697.0]/Border[0 0 0]/Dest[849 0 R/XYZ null 260 0]>>endobj
-390 0 obj<</Subtype/Link/Rect[108.0 670.8 200.6 683.8]/Border[0 0 0]/Dest[852 0 R/XYZ null 768 0]>>endobj
-391 0 obj<</Subtype/Link/Rect[108.0 657.6 526.0 670.6]/Border[0 0 0]/Dest[852 0 R/XYZ null 529 0]>>endobj
-392 0 obj<</Subtype/Link/Rect[108.0 644.4 500.6 657.4]/Border[0 0 0]/Dest[855 0 R/XYZ null 633 0]>>endobj
-393 0 obj<</Subtype/Link/Rect[108.0 631.2 353.3 644.2]/Border[0 0 0]/Dest[858 0 R/XYZ null 581 0]>>endobj
-394 0 obj<</Subtype/Link/Rect[108.0 618.0 419.0 631.0]/Border[0 0 0]/Dest[858 0 R/XYZ null 304 0]>>endobj
-395 0 obj<</Subtype/Link/Rect[108.0 604.8 332.5 617.8]/Border[0 0 0]/Dest[861 0 R/XYZ null 594 0]>>endobj
-396 0 obj<</Subtype/Link/Rect[108.0 591.6 181.6 604.6]/Border[0 0 0]/Dest[864 0 R/XYZ null 639 0]>>endobj
-397 0 obj<</Subtype/Link/Rect[72.0 565.2 463.4 578.2]/Border[0 0 0]/Dest[867 0 R/XYZ null 798 0]>>endobj
-398 0 obj<</Subtype/Link/Rect[108.0 552.0 202.4 565.0]/Border[0 0 0]/Dest[867 0 R/XYZ null 706 0]>>endobj
-399 0 obj<</Subtype/Link/Rect[108.0 538.8 244.9 551.8]/Border[0 0 0]/Dest[870 0 R/XYZ null 179 0]>>endobj
-400 0 obj<</Subtype/Link/Rect[108.0 525.6 270.3 538.6]/Border[0 0 0]/Dest[873 0 R/XYZ null 726 0]>>endobj
-401 0 obj<</Subtype/Link/Rect[72.0 499.2 402.3 512.2]/Border[0 0 0]/Dest[876 0 R/XYZ null 798 0]>>endobj
-402 0 obj<</Subtype/Link/Rect[108.0 486.0 179.2 499.0]/Border[0 0 0]/Dest[876 0 R/XYZ null 706 0]>>endobj
-403 0 obj<</Subtype/Link/Rect[108.0 472.8 161.2 485.8]/Border[0 0 0]/Dest[879 0 R/XYZ null 673 0]>>endobj
-404 0 obj<</Subtype/Link/Rect[72.0 446.4 412.7 459.4]/Border[0 0 0]/Dest[882 0 R/XYZ null 798 0]>>endobj
-405 0 obj<</Subtype/Link/Rect[108.0 433.2 447.4 446.2]/Border[0 0 0]/Dest[882 0 R/XYZ null 706 0]>>endobj
-406 0 obj<</Subtype/Link/Rect[108.0 420.0 319.1 433.0]/Border[0 0 0]/Dest[882 0 R/XYZ null 525 0]>>endobj
-407 0 obj<</Subtype/Link/Rect[108.0 406.8 231.1 419.8]/Border[0 0 0]/Dest[882 0 R/XYZ null 348 0]>>endobj
-408 0 obj<</Subtype/Link/Rect[108.0 393.6 292.2 406.6]/Border[0 0 0]/Dest[885 0 R/XYZ null 686 0]>>endobj
-409 0 obj<</Subtype/Link/Rect[108.0 380.4 208.5 393.4]/Border[0 0 0]/Dest[885 0 R/XYZ null 443 0]>>endobj
-410 0 obj<</Subtype/Link/Rect[108.0 367.2 233.6 380.2]/Border[0 0 0]/Dest[885 0 R/XYZ null 187 0]>>endobj
-411 0 obj<</Subtype/Link/Rect[108.0 354.0 301.4 367.0]/Border[0 0 0]/Dest[888 0 R/XYZ null 673 0]>>endobj
-412 0 obj<</Subtype/Link/Rect[108.0 340.8 394.8 353.8]/Border[0 0 0]/Dest[888 0 R/XYZ null 232 0]>>endobj
-413 0 obj<</Subtype/Link/Rect[108.0 327.6 386.9 340.6]/Border[0 0 0]/Dest[894 0 R/XYZ null 594 0]>>endobj
-414 0 obj<</Subtype/Link/Rect[72.0 301.2 277.1 314.2]/Border[0 0 0]/Dest[897 0 R/XYZ null 798 0]>>endobj
-415 0 obj<</Subtype/Link/Rect[108.0 288.0 181.6 301.0]/Border[0 0 0]/Dest[897 0 R/XYZ null 730 0]>>endobj
-416 0 obj<</Subtype/Link/Rect[108.0 274.8 189.0 287.8]/Border[0 0 0]/Dest[897 0 R/XYZ null 302 0]>>endobj
-417 0 obj<</Subtype/Link/Rect[108.0 261.6 209.7 274.6]/Border[0 0 0]/Dest[900 0 R/XYZ null 693 0]>>endobj
-418 0 obj<</Subtype/Link/Rect[108.0 248.4 294.4 261.4]/Border[0 0 0]/Dest[903 0 R/XYZ null 450 0]>>endobj
-419 0 obj<</Subtype/Link/Rect[108.0 235.2 287.3 248.2]/Border[0 0 0]/Dest[906 0 R/XYZ null 686 0]>>endobj
-420 0 obj<</Subtype/Link/Rect[108.0 222.0 350.9 235.0]/Border[0 0 0]/Dest[906 0 R/XYZ null 302 0]>>endobj
-421 0 obj<</Subtype/Link/Rect[108.0 208.8 242.1 221.8]/Border[0 0 0]/Dest[909 0 R/XYZ null 686 0]>>endobj
-422 0 obj<</Subtype/Link/Rect[108.0 195.6 220.1 208.6]/Border[0 0 0]/Dest[909 0 R/XYZ null 496 0]>>endobj
-423 0 obj<</Subtype/Link/Rect[108.0 182.4 214.3 195.4]/Border[0 0 0]/Dest[909 0 R/XYZ null 385 0]>>endobj
-424 0 obj<</Subtype/Link/Rect[108.0 169.2 281.2 182.2]/Border[0 0 0]/Dest[909 0 R/XYZ null 247 0]>>endobj
-425 0 obj<</Subtype/Link/Rect[108.0 156.0 222.3 169.0]/Border[0 0 0]/Dest[909 0 R/XYZ null 149 0]>>endobj
-426 0 obj<</Subtype/Link/Rect[108.0 142.8 234.5 155.8]/Border[0 0 0]/Dest[912 0 R/XYZ null 713 0]>>endobj
-427 0 obj<</Subtype/Link/Rect[108.0 129.6 300.2 142.6]/Border[0 0 0]/Dest[915 0 R/XYZ null 768 0]>>endobj
-428 0 obj<</Subtype/Link/Rect[72.0 103.2 264.8 116.2]/Border[0 0 0]/Dest[918 0 R/XYZ null 798 0]>>endobj
-429 0 obj<</Subtype/Link/Rect[108.0 90.0 181.6 103.0]/Border[0 0 0]/Dest[918 0 R/XYZ null 730 0]>>endobj
-430 0 obj<</Subtype/Link/Rect[108.0 76.8 251.9 89.8]/Border[0 0 0]/Dest[921 0 R/XYZ null 768 0]>>endobj
-431 0 obj<</Subtype/Link/Rect[108.0 63.6 236.0 76.6]/Border[0 0 0]/Dest[921 0 R/XYZ null 300 0]>>endobj
-432 0 obj[389 0 R
+388 0 R
+389 0 R
390 0 R
391 0 R
392 0 R
@@ -648,8 +642,53 @@
414 0 R
415 0 R
416 0 R
-417 0 R
-418 0 R
+]endobj
+418 0 obj<</Subtype/Link/Rect[72.0 684.0 512.6 697.0]/Border[0 0 0]/Dest[807 0 R/XYZ null 798 0]>>endobj
+419 0 obj<</Subtype/Link/Rect[108.0 670.8 219.2 683.8]/Border[0 0 0]/Dest[807 0 R/XYZ null 706 0]>>endobj
+420 0 obj<</Subtype/Link/Rect[108.0 657.6 181.0 670.6]/Border[0 0 0]/Dest[807 0 R/XYZ null 621 0]>>endobj
+421 0 obj<</Subtype/Link/Rect[108.0 644.4 359.1 657.4]/Border[0 0 0]/Dest[807 0 R/XYZ null 239 0]>>endobj
+422 0 obj<</Subtype/Link/Rect[108.0 631.2 364.3 644.2]/Border[0 0 0]/Dest[810 0 R/XYZ null 768 0]>>endobj
+423 0 obj<</Subtype/Link/Rect[108.0 618.0 251.0 631.0]/Border[0 0 0]/Dest[810 0 R/XYZ null 630 0]>>endobj
+424 0 obj<</Subtype/Link/Rect[108.0 604.8 325.8 617.8]/Border[0 0 0]/Dest[810 0 R/XYZ null 532 0]>>endobj
+425 0 obj<</Subtype/Link/Rect[108.0 591.6 268.1 604.6]/Border[0 0 0]/Dest[810 0 R/XYZ null 381 0]>>endobj
+426 0 obj<</Subtype/Link/Rect[108.0 578.4 309.6 591.4]/Border[0 0 0]/Dest[813 0 R/XYZ null 650 0]>>endobj
+427 0 obj<</Subtype/Link/Rect[72.0 552.0 484.2 565.0]/Border[0 0 0]/Dest[816 0 R/XYZ null 798 0]>>endobj
+428 0 obj<</Subtype/Link/Rect[108.0 538.8 168.2 551.8]/Border[0 0 0]/Dest[816 0 R/XYZ null 706 0]>>endobj
+429 0 obj<</Subtype/Link/Rect[108.0 525.6 187.1 538.6]/Border[0 0 0]/Dest[816 0 R/XYZ null 437 0]>>endobj
+430 0 obj<</Subtype/Link/Rect[108.0 512.4 245.2 525.4]/Border[0 0 0]/Dest[819 0 R/XYZ null 581 0]>>endobj
+431 0 obj<</Subtype/Link/Rect[108.0 499.2 384.2 512.2]/Border[0 0 0]/Dest[819 0 R/XYZ null 469 0]>>endobj
+432 0 obj<</Subtype/Link/Rect[108.0 486.0 273.0 499.0]/Border[0 0 0]/Dest[822 0 R/XYZ null 739 0]>>endobj
+433 0 obj<</Subtype/Link/Rect[108.0 472.8 255.6 485.8]/Border[0 0 0]/Dest[822 0 R/XYZ null 709 0]>>endobj
+434 0 obj<</Subtype/Link/Rect[108.0 459.6 227.5 472.6]/Border[0 0 0]/Dest[825 0 R/XYZ null 768 0]>>endobj
+435 0 obj<</Subtype/Link/Rect[108.0 446.4 287.0 459.4]/Border[0 0 0]/Dest[825 0 R/XYZ null 180 0]>>endobj
+436 0 obj<</Subtype/Link/Rect[108.0 433.2 256.2 446.2]/Border[0 0 0]/Dest[828 0 R/XYZ null 633 0]>>endobj
+437 0 obj<</Subtype/Link/Rect[108.0 420.0 330.7 433.0]/Border[0 0 0]/Dest[828 0 R/XYZ null 240 0]>>endobj
+438 0 obj<</Subtype/Link/Rect[108.0 406.8 324.3 419.8]/Border[0 0 0]/Dest[831 0 R/XYZ null 211 0]>>endobj
+439 0 obj<</Subtype/Link/Rect[108.0 393.6 185.9 406.6]/Border[0 0 0]/Dest[834 0 R/XYZ null 362 0]>>endobj
+440 0 obj<</Subtype/Link/Rect[72.0 367.2 431.7 380.2]/Border[0 0 0]/Dest[837 0 R/XYZ null 798 0]>>endobj
+441 0 obj<</Subtype/Link/Rect[108.0 354.0 170.0 367.0]/Border[0 0 0]/Dest[837 0 R/XYZ null 706 0]>>endobj
+442 0 obj<</Subtype/Link/Rect[108.0 340.8 187.1 353.8]/Border[0 0 0]/Dest[837 0 R/XYZ null 569 0]>>endobj
+443 0 obj<</Subtype/Link/Rect[108.0 327.6 239.1 340.6]/Border[0 0 0]/Dest[837 0 R/XYZ null 246 0]>>endobj
+444 0 obj<</Subtype/Link/Rect[108.0 314.4 193.8 327.4]/Border[0 0 0]/Dest[840 0 R/XYZ null 581 0]>>endobj
+445 0 obj<</Subtype/Link/Rect[108.0 301.2 227.5 314.2]/Border[0 0 0]/Dest[840 0 R/XYZ null 417 0]>>endobj
+446 0 obj<</Subtype/Link/Rect[108.0 288.0 294.1 301.0]/Border[0 0 0]/Dest[840 0 R/XYZ null 292 0]>>endobj
+447 0 obj<</Subtype/Link/Rect[108.0 274.8 236.3 287.8]/Border[0 0 0]/Dest[843 0 R/XYZ null 768 0]>>endobj
+448 0 obj<</Subtype/Link/Rect[108.0 261.6 294.4 274.6]/Border[0 0 0]/Dest[843 0 R/XYZ null 313 0]>>endobj
+449 0 obj<</Subtype/Link/Rect[108.0 248.4 274.8 261.4]/Border[0 0 0]/Dest[846 0 R/XYZ null 673 0]>>endobj
+450 0 obj<</Subtype/Link/Rect[108.0 235.2 208.5 248.2]/Border[0 0 0]/Dest[846 0 R/XYZ null 483 0]>>endobj
+451 0 obj<</Subtype/Link/Rect[108.0 222.0 265.4 235.0]/Border[0 0 0]/Dest[846 0 R/XYZ null 332 0]>>endobj
+452 0 obj<</Subtype/Link/Rect[108.0 208.8 195.4 221.8]/Border[0 0 0]/Dest[846 0 R/XYZ null 221 0]>>endobj
+453 0 obj<</Subtype/Link/Rect[108.0 195.6 202.1 208.6]/Border[0 0 0]/Dest[849 0 R/XYZ null 581 0]>>endobj
+454 0 obj<</Subtype/Link/Rect[108.0 182.4 226.6 195.4]/Border[0 0 0]/Dest[849 0 R/XYZ null 298 0]>>endobj
+455 0 obj<</Subtype/Link/Rect[108.0 169.2 183.5 182.2]/Border[0 0 0]/Dest[864 0 R/XYZ null 355 0]>>endobj
+456 0 obj<</Subtype/Link/Rect[108.0 156.0 182.9 169.0]/Border[0 0 0]/Dest[867 0 R/XYZ null 768 0]>>endobj
+457 0 obj<</Subtype/Link/Rect[72.0 129.6 228.8 142.6]/Border[0 0 0]/Dest[870 0 R/XYZ null 798 0]>>endobj
+458 0 obj<</Subtype/Link/Rect[108.0 116.4 159.0 129.4]/Border[0 0 0]/Dest[870 0 R/XYZ null 730 0]>>endobj
+459 0 obj<</Subtype/Link/Rect[108.0 103.2 499.0 116.2]/Border[0 0 0]/Dest[870 0 R/XYZ null 700 0]>>endobj
+460 0 obj<</Subtype/Link/Rect[108.0 90.0 504.2 103.0]/Border[0 0 0]/Dest[870 0 R/XYZ null 348 0]>>endobj
+461 0 obj<</Subtype/Link/Rect[108.0 76.8 455.7 89.8]/Border[0 0 0]/Dest[873 0 R/XYZ null 768 0]>>endobj
+462 0 obj<</Subtype/Link/Rect[108.0 63.6 425.4 76.6]/Border[0 0 0]/Dest[873 0 R/XYZ null 639 0]>>endobj
+463 0 obj[418 0 R
419 0 R
420 0 R
421 0 R
@@ -663,52 +702,8 @@
429 0 R
430 0 R
431 0 R
-]endobj
-433 0 obj<</Subtype/Link/Rect[108.0 684.0 287.0 697.0]/Border[0 0 0]/Dest[924 0 R/XYZ null 768 0]>>endobj
-434 0 obj<</Subtype/Link/Rect[108.0 670.8 210.4 683.8]/Border[0 0 0]/Dest[924 0 R/XYZ null 327 0]>>endobj
-435 0 obj<</Subtype/Link/Rect[108.0 657.6 231.1 670.6]/Border[0 0 0]/Dest[927 0 R/XYZ null 639 0]>>endobj
-436 0 obj<</Subtype/Link/Rect[108.0 644.4 229.3 657.4]/Border[0 0 0]/Dest[927 0 R/XYZ null 280 0]>>endobj
-437 0 obj<</Subtype/Link/Rect[108.0 631.2 210.0 644.2]/Border[0 0 0]/Dest[927 0 R/XYZ null 182 0]>>endobj
-438 0 obj<</Subtype/Link/Rect[108.0 618.0 196.6 631.0]/Border[0 0 0]/Dest[930 0 R/XYZ null 739 0]>>endobj
-439 0 obj<</Subtype/Link/Rect[72.0 591.6 192.4 604.6]/Border[0 0 0]/Dest[933 0 R/XYZ null 798 0]>>endobj
-440 0 obj<</Subtype/Link/Rect[108.0 578.4 181.6 591.4]/Border[0 0 0]/Dest[933 0 R/XYZ null 730 0]>>endobj
-441 0 obj<</Subtype/Link/Rect[108.0 565.2 323.7 578.2]/Border[0 0 0]/Dest[933 0 R/XYZ null 491 0]>>endobj
-442 0 obj<</Subtype/Link/Rect[72.0 538.8 278.4 551.8]/Border[0 0 0]/Dest[939 0 R/XYZ null 798 0]>>endobj
-443 0 obj<</Subtype/Link/Rect[108.0 525.6 305.4 538.6]/Border[0 0 0]/Dest[939 0 R/XYZ null 730 0]>>endobj
-444 0 obj<</Subtype/Link/Rect[108.0 512.4 293.5 525.4]/Border[0 0 0]/Dest[942 0 R/XYZ null 383 0]>>endobj
-445 0 obj<</Subtype/Link/Rect[108.0 499.2 313.4 512.2]/Border[0 0 0]/Dest[942 0 R/XYZ null 166 0]>>endobj
-446 0 obj<</Subtype/Link/Rect[72.0 472.8 431.7 485.8]/Border[0 0 0]/Dest[948 0 R/XYZ null 798 0]>>endobj
-447 0 obj<</Subtype/Link/Rect[108.0 459.6 170.0 472.6]/Border[0 0 0]/Dest[948 0 R/XYZ null 706 0]>>endobj
-448 0 obj<</Subtype/Link/Rect[108.0 446.4 187.1 459.4]/Border[0 0 0]/Dest[948 0 R/XYZ null 569 0]>>endobj
-449 0 obj<</Subtype/Link/Rect[108.0 433.2 239.1 446.2]/Border[0 0 0]/Dest[948 0 R/XYZ null 246 0]>>endobj
-450 0 obj<</Subtype/Link/Rect[108.0 420.0 193.8 433.0]/Border[0 0 0]/Dest[951 0 R/XYZ null 581 0]>>endobj
-451 0 obj<</Subtype/Link/Rect[108.0 406.8 227.5 419.8]/Border[0 0 0]/Dest[951 0 R/XYZ null 417 0]>>endobj
-452 0 obj<</Subtype/Link/Rect[108.0 393.6 294.1 406.6]/Border[0 0 0]/Dest[951 0 R/XYZ null 292 0]>>endobj
-453 0 obj<</Subtype/Link/Rect[108.0 380.4 236.3 393.4]/Border[0 0 0]/Dest[954 0 R/XYZ null 768 0]>>endobj
-454 0 obj<</Subtype/Link/Rect[108.0 367.2 294.4 380.2]/Border[0 0 0]/Dest[954 0 R/XYZ null 313 0]>>endobj
-455 0 obj<</Subtype/Link/Rect[108.0 354.0 274.8 367.0]/Border[0 0 0]/Dest[957 0 R/XYZ null 673 0]>>endobj
-456 0 obj<</Subtype/Link/Rect[108.0 340.8 208.5 353.8]/Border[0 0 0]/Dest[957 0 R/XYZ null 483 0]>>endobj
-457 0 obj<</Subtype/Link/Rect[108.0 327.6 265.4 340.6]/Border[0 0 0]/Dest[957 0 R/XYZ null 332 0]>>endobj
-458 0 obj<</Subtype/Link/Rect[108.0 314.4 195.4 327.4]/Border[0 0 0]/Dest[957 0 R/XYZ null 181 0]>>endobj
-459 0 obj<</Subtype/Link/Rect[108.0 301.2 202.1 314.2]/Border[0 0 0]/Dest[960 0 R/XYZ null 541 0]>>endobj
-460 0 obj<</Subtype/Link/Rect[108.0 288.0 226.6 301.0]/Border[0 0 0]/Dest[960 0 R/XYZ null 258 0]>>endobj
-461 0 obj<</Subtype/Link/Rect[108.0 274.8 183.5 287.8]/Border[0 0 0]/Dest[984 0 R/XYZ null 618 0]>>endobj
-462 0 obj<</Subtype/Link/Rect[108.0 261.6 182.9 274.6]/Border[0 0 0]/Dest[984 0 R/XYZ null 401 0]>>endobj
-463 0 obj<</Subtype/Link/Rect[72.0 235.2 421.8 248.2]/Border[0 0 0]/Dest[987 0 R/XYZ null 798 0]>>endobj
-464 0 obj<</Subtype/Link/Rect[108.0 222.0 224.7 235.0]/Border[0 0 0]/Dest[987 0 R/XYZ null 706 0]>>endobj
-465 0 obj<</Subtype/Link/Rect[108.0 208.8 186.5 221.8]/Border[0 0 0]/Dest[987 0 R/XYZ null 608 0]>>endobj
-466 0 obj<</Subtype/Link/Rect[108.0 195.6 321.6 208.6]/Border[0 0 0]/Dest[990 0 R/XYZ null 726 0]>>endobj
-467 0 obj<</Subtype/Link/Rect[108.0 182.4 435.5 195.4]/Border[0 0 0]/Dest[993 0 R/XYZ null 607 0]>>endobj
-468 0 obj<</Subtype/Link/Rect[108.0 169.2 338.7 182.2]/Border[0 0 0]/Dest[993 0 R/XYZ null 215 0]>>endobj
-469 0 obj<</Subtype/Link/Rect[108.0 156.0 368.0 169.0]/Border[0 0 0]/Dest[996 0 R/XYZ null 332 0]>>endobj
-470 0 obj<</Subtype/Link/Rect[108.0 142.8 284.9 155.8]/Border[0 0 0]/Dest[999 0 R/XYZ null 768 0]>>endobj
-471 0 obj<</Subtype/Link/Rect[108.0 129.6 266.9 142.6]/Border[0 0 0]/Dest[999 0 R/XYZ null 392 0]>>endobj
-472 0 obj<</Subtype/Link/Rect[108.0 116.4 258.3 129.4]/Border[0 0 0]/Dest[1005 0 R/XYZ null 739 0]>>endobj
-473 0 obj<</Subtype/Link/Rect[108.0 103.2 249.1 116.2]/Border[0 0 0]/Dest[1008 0 R/XYZ null 686 0]>>endobj
-474 0 obj<</Subtype/Link/Rect[108.0 90.0 298.4 103.0]/Border[0 0 0]/Dest[1014 0 R/XYZ null 303 0]>>endobj
-475 0 obj<</Subtype/Link/Rect[108.0 76.8 337.5 89.8]/Border[0 0 0]/Dest[1017 0 R/XYZ null 277 0]>>endobj
-476 0 obj<</Subtype/Link/Rect[108.0 63.6 411.7 76.6]/Border[0 0 0]/Dest[1020 0 R/XYZ null 482 0]>>endobj
-477 0 obj[433 0 R
+432 0 R
+433 0 R
434 0 R
435 0 R
436 0 R
@@ -738,419 +733,242 @@
460 0 R
461 0 R
462 0 R
-463 0 R
-464 0 R
+]endobj
+464 0 obj<</Subtype/Link/Rect[72.0 684.0 342.4 697.0]/Border[0 0 0]/Dest[876 0 R/XYZ null 798 0]>>endobj
+465 0 obj<</Subtype/Link/Rect[108.0 670.8 187.1 683.8]/Border[0 0 0]/Dest[876 0 R/XYZ null 706 0]>>endobj
+466 0 obj<</Subtype/Link/Rect[108.0 657.6 247.6 670.6]/Border[0 0 0]/Dest[876 0 R/XYZ null 582 0]>>endobj
+467 0 obj<</Subtype/Link/Rect[108.0 644.4 230.8 657.4]/Border[0 0 0]/Dest[876 0 R/XYZ null 484 0]>>endobj
+468 0 obj<</Subtype/Link/Rect[108.0 631.2 205.8 644.2]/Border[0 0 0]/Dest[876 0 R/XYZ null 359 0]>>endobj
+469 0 obj<</Subtype/Link/Rect[72.0 618.0 97.0 631.0]/Border[0 0 0]/Dest[879 0 R/XYZ null 503 0]>>endobj
+470 0 obj[464 0 R
465 0 R
466 0 R
467 0 R
468 0 R
469 0 R
-470 0 R
-471 0 R
-472 0 R
-473 0 R
-474 0 R
-475 0 R
-476 0 R
]endobj
-478 0 obj<</Subtype/Link/Rect[108.0 684.0 436.5 697.0]/Border[0 0 0]/Dest[1032 0 R/XYZ null 274 0]>>endobj
-479 0 obj<</Subtype/Link/Rect[72.0 657.6 518.1 670.6]/Border[0 0 0]/Dest[1041 0 R/XYZ null 798 0]>>endobj
-480 0 obj<</Subtype/Link/Rect[108.0 644.4 224.7 657.4]/Border[0 0 0]/Dest[1041 0 R/XYZ null 706 0]>>endobj
-481 0 obj<</Subtype/Link/Rect[108.0 631.2 186.5 644.2]/Border[0 0 0]/Dest[1041 0 R/XYZ null 621 0]>>endobj
-482 0 obj<</Subtype/Link/Rect[108.0 618.0 364.6 631.0]/Border[0 0 0]/Dest[1041 0 R/XYZ null 239 0]>>endobj
-483 0 obj<</Subtype/Link/Rect[108.0 604.8 369.8 617.8]/Border[0 0 0]/Dest[1044 0 R/XYZ null 768 0]>>endobj
-484 0 obj<</Subtype/Link/Rect[108.0 591.6 256.5 604.6]/Border[0 0 0]/Dest[1044 0 R/XYZ null 630 0]>>endobj
-485 0 obj<</Subtype/Link/Rect[108.0 578.4 331.3 591.4]/Border[0 0 0]/Dest[1044 0 R/XYZ null 532 0]>>endobj
-486 0 obj<</Subtype/Link/Rect[108.0 565.2 273.6 578.2]/Border[0 0 0]/Dest[1044 0 R/XYZ null 381 0]>>endobj
-487 0 obj<</Subtype/Link/Rect[108.0 552.0 315.1 565.0]/Border[0 0 0]/Dest[1047 0 R/XYZ null 650 0]>>endobj
-488 0 obj<</Subtype/Link/Rect[72.0 525.6 484.2 538.6]/Border[0 0 0]/Dest[1050 0 R/XYZ null 798 0]>>endobj
-489 0 obj<</Subtype/Link/Rect[108.0 512.4 168.2 525.4]/Border[0 0 0]/Dest[1050 0 R/XYZ null 706 0]>>endobj
-490 0 obj<</Subtype/Link/Rect[108.0 499.2 187.1 512.2]/Border[0 0 0]/Dest[1050 0 R/XYZ null 437 0]>>endobj
-491 0 obj<</Subtype/Link/Rect[108.0 486.0 245.2 499.0]/Border[0 0 0]/Dest[1053 0 R/XYZ null 581 0]>>endobj
-492 0 obj<</Subtype/Link/Rect[108.0 472.8 384.2 485.8]/Border[0 0 0]/Dest[1053 0 R/XYZ null 469 0]>>endobj
-493 0 obj<</Subtype/Link/Rect[108.0 459.6 273.0 472.6]/Border[0 0 0]/Dest[1056 0 R/XYZ null 739 0]>>endobj
-494 0 obj<</Subtype/Link/Rect[108.0 446.4 255.6 459.4]/Border[0 0 0]/Dest[1056 0 R/XYZ null 709 0]>>endobj
-495 0 obj<</Subtype/Link/Rect[108.0 433.2 227.5 446.2]/Border[0 0 0]/Dest[1059 0 R/XYZ null 768 0]>>endobj
-496 0 obj<</Subtype/Link/Rect[108.0 420.0 287.0 433.0]/Border[0 0 0]/Dest[1059 0 R/XYZ null 180 0]>>endobj
-497 0 obj<</Subtype/Link/Rect[108.0 406.8 256.2 419.8]/Border[0 0 0]/Dest[1062 0 R/XYZ null 633 0]>>endobj
-498 0 obj<</Subtype/Link/Rect[108.0 393.6 330.7 406.6]/Border[0 0 0]/Dest[1062 0 R/XYZ null 240 0]>>endobj
-499 0 obj<</Subtype/Link/Rect[108.0 380.4 324.3 393.4]/Border[0 0 0]/Dest[1065 0 R/XYZ null 211 0]>>endobj
-500 0 obj<</Subtype/Link/Rect[108.0 367.2 185.9 380.2]/Border[0 0 0]/Dest[1068 0 R/XYZ null 362 0]>>endobj
-501 0 obj<</Subtype/Link/Rect[72.0 340.8 268.2 353.8]/Border[0 0 0]/Dest[1071 0 R/XYZ null 798 0]>>endobj
-502 0 obj<</Subtype/Link/Rect[108.0 327.6 231.7 340.6]/Border[0 0 0]/Dest[1071 0 R/XYZ null 730 0]>>endobj
-503 0 obj<</Subtype/Link/Rect[108.0 314.4 253.4 327.4]/Border[0 0 0]/Dest[1071 0 R/XYZ null 540 0]>>endobj
-504 0 obj<</Subtype/Link/Rect[108.0 301.2 216.8 314.2]/Border[0 0 0]/Dest[1074 0 R/XYZ null 768 0]>>endobj
-505 0 obj<</Subtype/Link/Rect[108.0 288.0 241.5 301.0]/Border[0 0 0]/Dest[1074 0 R/XYZ null 471 0]>>endobj
-506 0 obj<</Subtype/Link/Rect[108.0 274.8 318.8 287.8]/Border[0 0 0]/Dest[1074 0 R/XYZ null 202 0]>>endobj
-507 0 obj<</Subtype/Link/Rect[108.0 261.6 245.8 274.6]/Border[0 0 0]/Dest[1083 0 R/XYZ null 447 0]>>endobj
-508 0 obj<</Subtype/Link/Rect[108.0 248.4 315.8 261.4]/Border[0 0 0]/Dest[1086 0 R/XYZ null 488 0]>>endobj
-509 0 obj<</Subtype/Link/Rect[108.0 235.2 290.1 248.2]/Border[0 0 0]/Dest[1089 0 R/XYZ null 492 0]>>endobj
-510 0 obj<</Subtype/Link/Rect[108.0 222.0 270.5 235.0]/Border[0 0 0]/Dest[1092 0 R/XYZ null 768 0]>>endobj
-511 0 obj<</Subtype/Link/Rect[108.0 208.8 281.8 221.8]/Border[0 0 0]/Dest[1092 0 R/XYZ null 339 0]>>endobj
-512 0 obj<</Subtype/Link/Rect[108.0 195.6 276.6 208.6]/Border[0 0 0]/Dest[1095 0 R/XYZ null 567 0]>>endobj
-513 0 obj<</Subtype/Link/Rect[108.0 182.4 221.7 195.4]/Border[0 0 0]/Dest[1095 0 R/XYZ null 469 0]>>endobj
-514 0 obj<</Subtype/Link/Rect[72.0 156.0 255.6 169.0]/Border[0 0 0]/Dest[1098 0 R/XYZ null 798 0]>>endobj
-515 0 obj<</Subtype/Link/Rect[108.0 142.8 190.8 155.8]/Border[0 0 0]/Dest[1098 0 R/XYZ null 730 0]>>endobj
-516 0 obj<</Subtype/Link/Rect[108.0 129.6 169.4 142.6]/Border[0 0 0]/Dest[1098 0 R/XYZ null 474 0]>>endobj
-517 0 obj<</Subtype/Link/Rect[108.0 116.4 184.4 129.4]/Border[0 0 0]/Dest[1098 0 R/XYZ null 444 0]>>endobj
-518 0 obj<</Subtype/Link/Rect[108.0 103.2 211.0 116.2]/Border[0 0 0]/Dest[1098 0 R/XYZ null 161 0]>>endobj
-519 0 obj<</Subtype/Link/Rect[108.0 90.0 310.3 103.0]/Border[0 0 0]/Dest[1101 0 R/XYZ null 647 0]>>endobj
-520 0 obj<</Subtype/Link/Rect[108.0 76.8 197.8 89.8]/Border[0 0 0]/Dest[1101 0 R/XYZ null 483 0]>>endobj
-521 0 obj<</Subtype/Link/Rect[108.0 63.6 175.2 76.6]/Border[0 0 0]/Dest[1101 0 R/XYZ null 213 0]>>endobj
-522 0 obj[478 0 R
-479 0 R
-480 0 R
-481 0 R
-482 0 R
-483 0 R
-484 0 R
-485 0 R
-486 0 R
-487 0 R
-488 0 R
-489 0 R
-490 0 R
-491 0 R
-492 0 R
-493 0 R
-494 0 R
-495 0 R
-496 0 R
-497 0 R
-498 0 R
-499 0 R
-500 0 R
-501 0 R
-502 0 R
-503 0 R
-504 0 R
-505 0 R
-506 0 R
-507 0 R
-508 0 R
-509 0 R
-510 0 R
-511 0 R
-512 0 R
-513 0 R
-514 0 R
-515 0 R
-516 0 R
-517 0 R
-518 0 R
-519 0 R
-520 0 R
-521 0 R
-]endobj
-523 0 obj<</Subtype/Link/Rect[108.0 684.0 175.8 697.0]/Border[0 0 0]/Dest[1104 0 R/XYZ null 660 0]>>endobj
-524 0 obj<</Subtype/Link/Rect[108.0 670.8 169.4 683.8]/Border[0 0 0]/Dest[1104 0 R/XYZ null 469 0]>>endobj
-525 0 obj<</Subtype/Link/Rect[108.0 657.6 189.3 670.6]/Border[0 0 0]/Dest[1104 0 R/XYZ null 332 0]>>endobj
-526 0 obj<</Subtype/Link/Rect[108.0 644.4 174.6 657.4]/Border[0 0 0]/Dest[1107 0 R/XYZ null 768 0]>>endobj
-527 0 obj<</Subtype/Link/Rect[108.0 631.2 180.1 644.2]/Border[0 0 0]/Dest[1107 0 R/XYZ null 683 0]>>endobj
-528 0 obj<</Subtype/Link/Rect[108.0 618.0 180.1 631.0]/Border[0 0 0]/Dest[1107 0 R/XYZ null 585 0]>>endobj
-529 0 obj<</Subtype/Link/Rect[108.0 604.8 182.5 617.8]/Border[0 0 0]/Dest[1107 0 R/XYZ null 407 0]>>endobj
-530 0 obj<</Subtype/Link/Rect[108.0 591.6 208.2 604.6]/Border[0 0 0]/Dest[1107 0 R/XYZ null 270 0]>>endobj
-531 0 obj<</Subtype/Link/Rect[108.0 578.4 217.4 591.4]/Border[0 0 0]/Dest[1110 0 R/XYZ null 713 0]>>endobj
-532 0 obj<</Subtype/Link/Rect[108.0 565.2 194.8 578.2]/Border[0 0 0]/Dest[1110 0 R/XYZ null 535 0]>>endobj
-533 0 obj<</Subtype/Link/Rect[108.0 552.0 194.2 565.0]/Border[0 0 0]/Dest[1110 0 R/XYZ null 398 0]>>endobj
-534 0 obj<</Subtype/Link/Rect[108.0 538.8 196.0 551.8]/Border[0 0 0]/Dest[1110 0 R/XYZ null 313 0]>>endobj
-535 0 obj<</Subtype/Link/Rect[108.0 525.6 188.7 538.6]/Border[0 0 0]/Dest[1113 0 R/XYZ null 264 0]>>endobj
-536 0 obj<</Subtype/Link/Rect[72.0 499.2 228.8 512.2]/Border[0 0 0]/Dest[1119 0 R/XYZ null 798 0]>>endobj
-537 0 obj<</Subtype/Link/Rect[108.0 486.0 159.0 499.0]/Border[0 0 0]/Dest[1119 0 R/XYZ null 730 0]>>endobj
-538 0 obj<</Subtype/Link/Rect[108.0 472.8 499.0 485.8]/Border[0 0 0]/Dest[1119 0 R/XYZ null 700 0]>>endobj
-539 0 obj<</Subtype/Link/Rect[108.0 459.6 504.2 472.6]/Border[0 0 0]/Dest[1119 0 R/XYZ null 348 0]>>endobj
-540 0 obj<</Subtype/Link/Rect[108.0 446.4 455.7 459.4]/Border[0 0 0]/Dest[1122 0 R/XYZ null 768 0]>>endobj
-541 0 obj<</Subtype/Link/Rect[108.0 433.2 425.4 446.2]/Border[0 0 0]/Dest[1122 0 R/XYZ null 639 0]>>endobj
-542 0 obj<</Subtype/Link/Rect[72.0 406.8 342.4 419.8]/Border[0 0 0]/Dest[1125 0 R/XYZ null 798 0]>>endobj
-543 0 obj<</Subtype/Link/Rect[108.0 393.6 187.1 406.6]/Border[0 0 0]/Dest[1125 0 R/XYZ null 706 0]>>endobj
-544 0 obj<</Subtype/Link/Rect[108.0 380.4 247.6 393.4]/Border[0 0 0]/Dest[1125 0 R/XYZ null 582 0]>>endobj
-545 0 obj<</Subtype/Link/Rect[108.0 367.2 230.8 380.2]/Border[0 0 0]/Dest[1125 0 R/XYZ null 484 0]>>endobj
-546 0 obj<</Subtype/Link/Rect[108.0 354.0 205.8 367.0]/Border[0 0 0]/Dest[1125 0 R/XYZ null 359 0]>>endobj
-547 0 obj<</Subtype/Link/Rect[72.0 327.6 204.0 340.6]/Border[0 0 0]/Dest[1131 0 R/XYZ null 798 0]>>endobj
-548 0 obj<</Subtype/Link/Rect[108.0 314.4 187.1 327.4]/Border[0 0 0]/Dest[1131 0 R/XYZ null 730 0]>>endobj
-549 0 obj<</Subtype/Link/Rect[108.0 301.2 188.0 314.2]/Border[0 0 0]/Dest[1131 0 R/XYZ null 461 0]>>endobj
-550 0 obj<</Subtype/Link/Rect[108.0 288.0 190.5 301.0]/Border[0 0 0]/Dest[1131 0 R/XYZ null 310 0]>>endobj
-551 0 obj<</Subtype/Link/Rect[108.0 274.8 195.4 287.8]/Border[0 0 0]/Dest[1134 0 R/XYZ null 633 0]>>endobj
-552 0 obj<</Subtype/Link/Rect[108.0 261.6 267.8 274.6]/Border[0 0 0]/Dest[1134 0 R/XYZ null 271 0]>>endobj
-553 0 obj<</Subtype/Link/Rect[108.0 248.4 166.4 261.4]/Border[0 0 0]/Dest[1134 0 R/XYZ null 160 0]>>endobj
-554 0 obj<</Subtype/Link/Rect[72.0 235.2 97.0 248.2]/Border[0 0 0]/Dest[1137 0 R/XYZ null 741 0]>>endobj
-555 0 obj[523 0 R
-524 0 R
-525 0 R
-526 0 R
-527 0 R
-528 0 R
-529 0 R
-530 0 R
-531 0 R
-532 0 R
-533 0 R
-534 0 R
-535 0 R
-536 0 R
-537 0 R
-538 0 R
-539 0 R
-540 0 R
-541 0 R
-542 0 R
-543 0 R
-544 0 R
-545 0 R
-546 0 R
-547 0 R
-548 0 R
-549 0 R
-550 0 R
-551 0 R
-552 0 R
-553 0 R
-554 0 R
-]endobj
-556 0 obj<</Dests 557 0 R>>endobj
-557 0 obj<</Kids[558 0 R]>>endobj
-558 0 obj<</Limits[(aen1022)(winbind)]/Names[(aen1022)559 0 R(aen1030)560 0 R(aen1034)561 0 R(aen1044)562 0 R(aen1047)563 0 R(aen1051)564 0 R(aen1073)565 0 R(aen1119)566 0 R(aen1135)567 0 R(aen1144)568 0 R(aen1152)569 0 R(aen1180)570 0 R(aen119)571 0 R(aen1191)572 0 R(aen1203)573 0 R(aen1206)574 0 R(aen1209)575 0 R(aen1222)576 0 R(aen1233)577 0 R(aen1266)578 0 R(aen1330)579 0 R(aen1335)580 0 R(aen135)581 0 R(aen1388)582 0 R(aen1392)583 0 R(aen1405)584 0 R(aen1412)585 0 R(aen1416)586 0 R(aen1421)587 0 R(aen1425)588 0 R(aen144)589 0 R(aen1441)590 0 R(aen1449)591 0 R(aen1453)592 0 R(aen1456)593 0 R(aen1463)594 0 R(aen1476)595 0 R(aen1490)596 0 R(aen1501)597 0 R(aen1520)598 0 R(aen1553)599 0 R(aen1569)600 0 R(aen1580)601 0 R(aen160)602 0 R(aen1616)603 0 R(aen1618)604 0 R(aen1635)605 0 R(aen1642)606 0 R(aen1648)607 0 R(aen1665)608 0 R(aen1698)609 0 R(aen1705)610 0 R(aen1715)611 0 R(aen1735)612 0 R(aen174)613 0 R(aen1741)614 0 R(aen1780)615 0 R(aen179)616 0 R(aen1823)617 0 R(aen183)618 0 R(aen1842)619 0 R(aen186)620 0 R(aen1877)621 0 R(aen1886)622 0 R(aen1901)623 0 R(aen1949)624 0 R(aen195)625 0 R(aen199)626 0 R(aen1993)627 0 R(aen20)628 0 R(aen208)629 0 R(aen2107)630 0 R(aen2133)631 0 R(aen2152)632 0 R(aen2160)633 0 R(aen2168)634 0 R(aen2176)635 0 R(aen2183)636 0 R(aen2219)637 0 R(aen222)638 0 R(aen2232)639 0 R(aen2235)640 0 R(aen2245)641 0 R(aen227)642 0 R(aen2281)643 0 R(aen2285)644 0 R(aen2293)645 0 R(aen2296)646 0 R(aen2299)647 0 R(aen2302)648 0 R(aen2306)649 0 R(aen2322)650 0 R(aen2343)651 0 R(aen2363)652 0 R(aen237)653 0 R(aen239)654 0 R(aen2392)655 0 R(aen2397)656 0 R(aen2409)657 0 R(aen2411)658 0 R(aen2428)659 0 R(aen245)660 0 R(aen2456)661 0 R(aen2461)662 0 R(aen2481)663 0 R(aen251)664 0 R(aen2551)665 0 R(aen2559)666 0 R(aen2570)667 0 R(aen2574)668 0 R(aen2583)669 0 R(aen2590)670 0 R(aen2595)671 0 R(aen2630)672 0 R(aen2649)673 0 R(aen266)674 0 R(aen2667)675 0 R(aen2677)676 0 R(aen2686)677 0 R(aen2704)678 0 R(aen2707)679 0 R(aen271)680 0 R(aen2725)681 0 R(aen2731)682 0 R(aen2733)683 0 R(aen2741)684 0 R(aen2747)685 0 R(aen2751)686 0 R(aen2758)687 0 R(aen2763)688 0 R(aen2768)689 0 R(aen277)690 0 R(aen2772)691 0 R(aen2777)692 0 R(aen2780)693 0 R(aen2783)694 0 R(aen2788)695 0 R(aen2792)696 0 R(aen2799)697 0 R(aen28)698 0 R(aen2804)699 0 R(aen2808)700 0 R(aen2811)701 0 R(aen2843)702 0 R(aen285)703 0 R(aen2860)704 0 R(aen2862)705 0 R(aen2877)706 0 R(aen2886)707 0 R(aen2890)708 0 R(aen2906)709 0 R(aen2911)710 0 R(aen2914)711 0 R(aen2919)712 0 R(aen2954)713 0 R(aen2961)714 0 R(aen2967)715 0 R(aen2984)716 0 R(aen2994)717 0 R(aen2997)718 0 R(aen3002)719 0 R(aen311)720 0 R(aen328)721 0 R(aen333)722 0 R(aen339)723 0 R(aen344)724 0 R(aen361)725 0 R(aen383)726 0 R(aen399)727 0 R(aen4)728 0 R(aen415)729 0 R(aen426)730 0 R(aen434)731 0 R(aen446)732 0 R(aen458)733 0 R(aen463)734 0 R(aen471)735 0 R(aen476)736 0 R(aen479)737 0 R(aen491)738 0 R(aen501)739 0 R(aen529)740 0 R(aen537)741 0 R(aen554)742 0 R(aen56)743 0 R(aen561)744 0 R(aen566)745 0 R(aen571)746 0 R(aen592)747 0 R(aen60)748 0 R(aen636)749 0 R(aen643)750 0 R(aen663)751 0 R(aen698)752 0 R(aen718)753 0 R(aen727)754 0 R(aen738)755 0 R(aen74)756 0 R(aen758)757 0 R(aen773)758 0 R(aen787)759 0 R(aen794)760 0 R(aen8)761 0 R(aen80)762 0 R(aen816)763 0 R(aen880)764 0 R(aen90)765 0 R(aen901)766 0 R(aen923)767 0 R(aen934)768 0 R(aen969)769 0 R(aen986)770 0 R(aen997)771 0 R(body.html)772 0 R(bugreport)773 0 R(cvs-access)774 0 R(diagnosis)775 0 R(domain-security)776 0 R(improved-browsing)777 0 R(install)778 0 R(integrate-ms-networks)779 0 R(migration)780 0 R(msdfs)781 0 R(os2)782 0 R(pam)783 0 R(printing)784 0 R(printing_debug)785 0 R(samba-bdc)786 0 R(samba-ldap-howto)787 0 R(samba-pdc)788 0 R(samba-project-documentation)789 0 R(security_levels)790 0 R(speed)791 0 R(unix-permissions)792 0 R(winbind)793 0 R]>>endobj
-559 0 obj<</D[906 0 R/XYZ null 686 null]>>endobj
-560 0 obj<</D[906 0 R/XYZ null 496 null]>>endobj
-561 0 obj<</D[906 0 R/XYZ null 385 null]>>endobj
-562 0 obj<</D[906 0 R/XYZ null 247 null]>>endobj
-563 0 obj<</D[906 0 R/XYZ null 149 null]>>endobj
-564 0 obj<</D[909 0 R/XYZ null 713 null]>>endobj
-565 0 obj<</D[912 0 R/XYZ null 768 null]>>endobj
-566 0 obj<</D[915 0 R/XYZ null 730 null]>>endobj
-567 0 obj<</D[918 0 R/XYZ null 768 null]>>endobj
-568 0 obj<</D[918 0 R/XYZ null 300 null]>>endobj
-569 0 obj<</D[921 0 R/XYZ null 768 null]>>endobj
-570 0 obj<</D[921 0 R/XYZ null 327 null]>>endobj
-571 0 obj<</D[801 0 R/XYZ null 266 null]>>endobj
-572 0 obj<</D[924 0 R/XYZ null 639 null]>>endobj
-573 0 obj<</D[924 0 R/XYZ null 280 null]>>endobj
-574 0 obj<</D[924 0 R/XYZ null 182 null]>>endobj
-575 0 obj<</D[927 0 R/XYZ null 739 null]>>endobj
-576 0 obj<</D[930 0 R/XYZ null 730 null]>>endobj
-577 0 obj<</D[930 0 R/XYZ null 491 null]>>endobj
-578 0 obj<</D[936 0 R/XYZ null 730 null]>>endobj
-579 0 obj<</D[939 0 R/XYZ null 383 null]>>endobj
-580 0 obj<</D[939 0 R/XYZ null 166 null]>>endobj
-581 0 obj<</D[804 0 R/XYZ null 686 null]>>endobj
-582 0 obj<</D[945 0 R/XYZ null 706 null]>>endobj
-583 0 obj<</D[945 0 R/XYZ null 569 null]>>endobj
-584 0 obj<</D[945 0 R/XYZ null 246 null]>>endobj
-585 0 obj<</D[948 0 R/XYZ null 581 null]>>endobj
-586 0 obj<</D[948 0 R/XYZ null 417 null]>>endobj
-587 0 obj<</D[948 0 R/XYZ null 292 null]>>endobj
-588 0 obj<</D[951 0 R/XYZ null 768 null]>>endobj
-589 0 obj<</D[804 0 R/XYZ null 509 null]>>endobj
-590 0 obj<</D[951 0 R/XYZ null 313 null]>>endobj
-591 0 obj<</D[954 0 R/XYZ null 673 null]>>endobj
-592 0 obj<</D[954 0 R/XYZ null 483 null]>>endobj
-593 0 obj<</D[954 0 R/XYZ null 332 null]>>endobj
-594 0 obj<</D[954 0 R/XYZ null 181 null]>>endobj
-595 0 obj<</D[957 0 R/XYZ null 541 null]>>endobj
-596 0 obj<</D[957 0 R/XYZ null 258 null]>>endobj
-597 0 obj<</D[960 0 R/XYZ null 753 null]>>endobj
-598 0 obj<</D[960 0 R/XYZ null 552 null]>>endobj
-599 0 obj<</D[960 0 R/XYZ null 134 null]>>endobj
-600 0 obj<</D[963 0 R/XYZ null 545 null]>>endobj
-601 0 obj<</D[963 0 R/XYZ null 385 null]>>endobj
-602 0 obj<</D[804 0 R/XYZ null 332 null]>>endobj
-603 0 obj<</D[966 0 R/XYZ null 324 null]>>endobj
-604 0 obj<</D[966 0 R/XYZ null 288 null]>>endobj
-605 0 obj<</D[969 0 R/XYZ null 359 null]>>endobj
-606 0 obj<</D[972 0 R/XYZ null 421 null]>>endobj
-607 0 obj<</D[972 0 R/XYZ null 353 null]>>endobj
-608 0 obj<</D[975 0 R/XYZ null 743 null]>>endobj
-609 0 obj<</D[978 0 R/XYZ null 743 null]>>endobj
-610 0 obj<</D[981 0 R/XYZ null 618 null]>>endobj
-611 0 obj<</D[981 0 R/XYZ null 401 null]>>endobj
-612 0 obj<</D[984 0 R/XYZ null 706 null]>>endobj
-613 0 obj<</D[807 0 R/XYZ null 768 null]>>endobj
-614 0 obj<</D[984 0 R/XYZ null 608 null]>>endobj
-615 0 obj<</D[987 0 R/XYZ null 726 null]>>endobj
-616 0 obj<</D[807 0 R/XYZ null 577 null]>>endobj
-617 0 obj<</D[990 0 R/XYZ null 607 null]>>endobj
-618 0 obj<</D[807 0 R/XYZ null 505 null]>>endobj
-619 0 obj<</D[990 0 R/XYZ null 215 null]>>endobj
-620 0 obj<</D[807 0 R/XYZ null 407 null]>>endobj
-621 0 obj<</D[993 0 R/XYZ null 332 null]>>endobj
-622 0 obj<</D[996 0 R/XYZ null 768 null]>>endobj
-623 0 obj<</D[996 0 R/XYZ null 392 null]>>endobj
-624 0 obj<</D[1002 0 R/XYZ null 739 null]>>endobj
-625 0 obj<</D[810 0 R/XYZ null 768 null]>>endobj
-626 0 obj<</D[810 0 R/XYZ null 643 null]>>endobj
-627 0 obj<</D[1005 0 R/XYZ null 686 null]>>endobj
-628 0 obj<</D[795 0 R/XYZ null 730 null]>>endobj
-629 0 obj<</D[810 0 R/XYZ null 175 null]>>endobj
-630 0 obj<</D[1011 0 R/XYZ null 303 null]>>endobj
-631 0 obj<</D[1014 0 R/XYZ null 277 null]>>endobj
-632 0 obj<</D[1017 0 R/XYZ null 482 null]>>endobj
-633 0 obj<</D[1017 0 R/XYZ null 225 null]>>endobj
-634 0 obj<</D[1020 0 R/XYZ null 684 null]>>endobj
-635 0 obj<</D[1020 0 R/XYZ null 446 null]>>endobj
-636 0 obj<</D[1020 0 R/XYZ null 289 null]>>endobj
-637 0 obj<</D[1026 0 R/XYZ null 605 null]>>endobj
-638 0 obj<</D[813 0 R/XYZ null 730 null]>>endobj
-639 0 obj<</D[1029 0 R/XYZ null 698 null]>>endobj
-640 0 obj<</D[1029 0 R/XYZ null 603 null]>>endobj
-641 0 obj<</D[1029 0 R/XYZ null 274 null]>>endobj
-642 0 obj<</D[813 0 R/XYZ null 553 null]>>endobj
-643 0 obj<</D[1038 0 R/XYZ null 706 null]>>endobj
-644 0 obj<</D[1038 0 R/XYZ null 621 null]>>endobj
-645 0 obj<</D[1038 0 R/XYZ null 239 null]>>endobj
-646 0 obj<</D[1041 0 R/XYZ null 768 null]>>endobj
-647 0 obj<</D[1041 0 R/XYZ null 630 null]>>endobj
-648 0 obj<</D[1041 0 R/XYZ null 532 null]>>endobj
-649 0 obj<</D[1041 0 R/XYZ null 381 null]>>endobj
-650 0 obj<</D[1044 0 R/XYZ null 650 null]>>endobj
-651 0 obj<</D[1047 0 R/XYZ null 706 null]>>endobj
-652 0 obj<</D[1047 0 R/XYZ null 437 null]>>endobj
-653 0 obj<</D[813 0 R/XYZ null 186 null]>>endobj
-654 0 obj<</D[813 0 R/XYZ null 156 null]>>endobj
-655 0 obj<</D[1050 0 R/XYZ null 581 null]>>endobj
-656 0 obj<</D[1050 0 R/XYZ null 469 null]>>endobj
-657 0 obj<</D[1053 0 R/XYZ null 739 null]>>endobj
-658 0 obj<</D[1053 0 R/XYZ null 709 null]>>endobj
-659 0 obj<</D[1056 0 R/XYZ null 768 null]>>endobj
-660 0 obj<</D[816 0 R/XYZ null 726 null]>>endobj
-661 0 obj<</D[1056 0 R/XYZ null 180 null]>>endobj
-662 0 obj<</D[1059 0 R/XYZ null 633 null]>>endobj
-663 0 obj<</D[1059 0 R/XYZ null 240 null]>>endobj
-664 0 obj<</D[816 0 R/XYZ null 509 null]>>endobj
-665 0 obj<</D[1062 0 R/XYZ null 211 null]>>endobj
-666 0 obj<</D[1065 0 R/XYZ null 362 null]>>endobj
-667 0 obj<</D[1068 0 R/XYZ null 730 null]>>endobj
-668 0 obj<</D[1068 0 R/XYZ null 540 null]>>endobj
-669 0 obj<</D[1071 0 R/XYZ null 768 null]>>endobj
-670 0 obj<</D[1071 0 R/XYZ null 471 null]>>endobj
-671 0 obj<</D[1071 0 R/XYZ null 202 null]>>endobj
-672 0 obj<</D[1080 0 R/XYZ null 447 null]>>endobj
-673 0 obj<</D[1083 0 R/XYZ null 488 null]>>endobj
-674 0 obj<</D[819 0 R/XYZ null 581 null]>>endobj
-675 0 obj<</D[1086 0 R/XYZ null 492 null]>>endobj
-676 0 obj<</D[1089 0 R/XYZ null 768 null]>>endobj
-677 0 obj<</D[1089 0 R/XYZ null 339 null]>>endobj
-678 0 obj<</D[1092 0 R/XYZ null 567 null]>>endobj
-679 0 obj<</D[1092 0 R/XYZ null 469 null]>>endobj
-680 0 obj<</D[819 0 R/XYZ null 417 null]>>endobj
-681 0 obj<</D[1095 0 R/XYZ null 730 null]>>endobj
-682 0 obj<</D[1095 0 R/XYZ null 474 null]>>endobj
-683 0 obj<</D[1095 0 R/XYZ null 444 null]>>endobj
-684 0 obj<</D[1095 0 R/XYZ null 161 null]>>endobj
-685 0 obj<</D[1098 0 R/XYZ null 647 null]>>endobj
-686 0 obj<</D[1098 0 R/XYZ null 483 null]>>endobj
-687 0 obj<</D[1098 0 R/XYZ null 213 null]>>endobj
-688 0 obj<</D[1101 0 R/XYZ null 660 null]>>endobj
-689 0 obj<</D[1101 0 R/XYZ null 469 null]>>endobj
-690 0 obj<</D[819 0 R/XYZ null 279 null]>>endobj
-691 0 obj<</D[1101 0 R/XYZ null 332 null]>>endobj
-692 0 obj<</D[1104 0 R/XYZ null 768 null]>>endobj
-693 0 obj<</D[1104 0 R/XYZ null 683 null]>>endobj
-694 0 obj<</D[1104 0 R/XYZ null 585 null]>>endobj
-695 0 obj<</D[1104 0 R/XYZ null 407 null]>>endobj
-696 0 obj<</D[1104 0 R/XYZ null 270 null]>>endobj
-697 0 obj<</D[1107 0 R/XYZ null 713 null]>>endobj
-698 0 obj<</D[795 0 R/XYZ null 593 null]>>endobj
-699 0 obj<</D[1107 0 R/XYZ null 535 null]>>endobj
-700 0 obj<</D[1107 0 R/XYZ null 398 null]>>endobj
-701 0 obj<</D[1107 0 R/XYZ null 313 null]>>endobj
-702 0 obj<</D[1110 0 R/XYZ null 264 null]>>endobj
-703 0 obj<</D[822 0 R/XYZ null 673 null]>>endobj
-704 0 obj<</D[1116 0 R/XYZ null 730 null]>>endobj
-705 0 obj<</D[1116 0 R/XYZ null 700 null]>>endobj
-706 0 obj<</D[1116 0 R/XYZ null 348 null]>>endobj
-707 0 obj<</D[1119 0 R/XYZ null 768 null]>>endobj
-708 0 obj<</D[1119 0 R/XYZ null 639 null]>>endobj
-709 0 obj<</D[1122 0 R/XYZ null 706 null]>>endobj
-710 0 obj<</D[1122 0 R/XYZ null 582 null]>>endobj
-711 0 obj<</D[1122 0 R/XYZ null 484 null]>>endobj
-712 0 obj<</D[1122 0 R/XYZ null 359 null]>>endobj
-713 0 obj<</D[1128 0 R/XYZ null 730 null]>>endobj
-714 0 obj<</D[1128 0 R/XYZ null 461 null]>>endobj
-715 0 obj<</D[1128 0 R/XYZ null 310 null]>>endobj
-716 0 obj<</D[1131 0 R/XYZ null 633 null]>>endobj
-717 0 obj<</D[1131 0 R/XYZ null 271 null]>>endobj
-718 0 obj<</D[1131 0 R/XYZ null 160 null]>>endobj
-719 0 obj<</D[1134 0 R/XYZ null 741 null]>>endobj
-720 0 obj<</D[822 0 R/XYZ null 298 null]>>endobj
-721 0 obj<</D[825 0 R/XYZ null 607 null]>>endobj
-722 0 obj<</D[825 0 R/XYZ null 430 null]>>endobj
-723 0 obj<</D[825 0 R/XYZ null 279 null]>>endobj
-724 0 obj<</D[828 0 R/XYZ null 768 null]>>endobj
-725 0 obj<</D[831 0 R/XYZ null 706 null]>>endobj
-726 0 obj<</D[831 0 R/XYZ null 463 null]>>endobj
-727 0 obj<</D[831 0 R/XYZ null 325 null]>>endobj
-728 0 obj<</D[792 0 R/XYZ null 647 null]>>endobj
-729 0 obj<</D[834 0 R/XYZ null 435 null]>>endobj
-730 0 obj<</D[834 0 R/XYZ null 285 null]>>endobj
-731 0 obj<</D[837 0 R/XYZ null 768 null]>>endobj
-732 0 obj<</D[837 0 R/XYZ null 268 null]>>endobj
-733 0 obj<</D[840 0 R/XYZ null 210 null]>>endobj
-734 0 obj<</D[843 0 R/XYZ null 660 null]>>endobj
-735 0 obj<</D[846 0 R/XYZ null 371 null]>>endobj
-736 0 obj<</D[846 0 R/XYZ null 260 null]>>endobj
-737 0 obj<</D[849 0 R/XYZ null 768 null]>>endobj
-738 0 obj<</D[849 0 R/XYZ null 529 null]>>endobj
-739 0 obj<</D[852 0 R/XYZ null 633 null]>>endobj
-740 0 obj<</D[855 0 R/XYZ null 581 null]>>endobj
-741 0 obj<</D[855 0 R/XYZ null 304 null]>>endobj
-742 0 obj<</D[858 0 R/XYZ null 594 null]>>endobj
-743 0 obj<</D[795 0 R/XYZ null 178 null]>>endobj
-744 0 obj<</D[858 0 R/XYZ null 271 null]>>endobj
-745 0 obj<</D[861 0 R/XYZ null 753 null]>>endobj
-746 0 obj<</D[861 0 R/XYZ null 639 null]>>endobj
-747 0 obj<</D[864 0 R/XYZ null 706 null]>>endobj
-748 0 obj<</D[798 0 R/XYZ null 739 null]>>endobj
-749 0 obj<</D[867 0 R/XYZ null 179 null]>>endobj
-750 0 obj<</D[870 0 R/XYZ null 726 null]>>endobj
-751 0 obj<</D[873 0 R/XYZ null 706 null]>>endobj
-752 0 obj<</D[876 0 R/XYZ null 673 null]>>endobj
-753 0 obj<</D[879 0 R/XYZ null 706 null]>>endobj
-754 0 obj<</D[879 0 R/XYZ null 525 null]>>endobj
-755 0 obj<</D[879 0 R/XYZ null 348 null]>>endobj
-756 0 obj<</D[798 0 R/XYZ null 379 null]>>endobj
-757 0 obj<</D[882 0 R/XYZ null 686 null]>>endobj
-758 0 obj<</D[882 0 R/XYZ null 443 null]>>endobj
-759 0 obj<</D[882 0 R/XYZ null 187 null]>>endobj
-760 0 obj<</D[885 0 R/XYZ null 673 null]>>endobj
-761 0 obj<</D[792 0 R/XYZ null 616 null]>>endobj
-762 0 obj<</D[798 0 R/XYZ null 268 null]>>endobj
-763 0 obj<</D[885 0 R/XYZ null 232 null]>>endobj
-764 0 obj<</D[891 0 R/XYZ null 594 null]>>endobj
-765 0 obj<</D[801 0 R/XYZ null 768 null]>>endobj
-766 0 obj<</D[894 0 R/XYZ null 730 null]>>endobj
-767 0 obj<</D[894 0 R/XYZ null 302 null]>>endobj
-768 0 obj<</D[897 0 R/XYZ null 693 null]>>endobj
-769 0 obj<</D[900 0 R/XYZ null 450 null]>>endobj
-770 0 obj<</D[903 0 R/XYZ null 686 null]>>endobj
-771 0 obj<</D[903 0 R/XYZ null 302 null]>>endobj
-772 0 obj<</D[798 0 R/XYZ null 698 null]>>endobj
-773 0 obj<</D[1128 0 R/XYZ null 798 null]>>endobj
-774 0 obj<</D[1122 0 R/XYZ null 798 null]>>endobj
-775 0 obj<</D[813 0 R/XYZ null 798 null]>>endobj
-776 0 obj<</D[936 0 R/XYZ null 798 null]>>endobj
-777 0 obj<</D[1068 0 R/XYZ null 798 null]>>endobj
-778 0 obj<</D[795 0 R/XYZ null 798 null]>>endobj
-779 0 obj<</D[831 0 R/XYZ null 798 null]>>endobj
-780 0 obj<</D[912 0 R/XYZ null 768 null]>>endobj
-781 0 obj<</D[873 0 R/XYZ null 798 null]>>endobj
-782 0 obj<</D[1116 0 R/XYZ null 798 null]>>endobj
-783 0 obj<</D[864 0 R/XYZ null 798 null]>>endobj
-784 0 obj<</D[894 0 R/XYZ null 798 null]>>endobj
-785 0 obj<</D[915 0 R/XYZ null 798 null]>>endobj
-786 0 obj<</D[1038 0 R/XYZ null 798 null]>>endobj
-787 0 obj<</D[1047 0 R/XYZ null 798 null]>>endobj
-788 0 obj<</D[984 0 R/XYZ null 798 null]>>endobj
-789 0 obj<</D[792 0 R/XYZ null 753 null]>>endobj
-790 0 obj<</D[930 0 R/XYZ null 798 null]>>endobj
-791 0 obj<</D[1095 0 R/XYZ null 798 null]>>endobj
-792 0 obj<</D[879 0 R/XYZ null 798 null]>>endobj
-793 0 obj<</D[945 0 R/XYZ null 798 null]>>endobj
-794 0 obj<</Type/Pages/MediaBox[0 0 595 792]/Count 120/Kids[795 0 R
-1140 0 R
-1143 0 R
-1146 0 R
-1149 0 R
-1152 0 R
+471 0 obj<</Dests 472 0 R>>endobj
+472 0 obj<</Kids[473 0 R]>>endobj
+473 0 obj<</Limits[(aen1056)(winbind)]/Names[(aen1056)474 0 R(aen1061)475 0 R(aen1094)476 0 R(aen1100)477 0 R(aen1139)478 0 R(aen1182)479 0 R(aen119)480 0 R(aen1201)481 0 R(aen1236)482 0 R(aen1245)483 0 R(aen1260)484 0 R(aen1308)485 0 R(aen135)486 0 R(aen1352)487 0 R(aen144)488 0 R(aen1466)489 0 R(aen1492)490 0 R(aen1511)491 0 R(aen1519)492 0 R(aen1527)493 0 R(aen1535)494 0 R(aen1542)495 0 R(aen1578)496 0 R(aen1591)497 0 R(aen1594)498 0 R(aen160)499 0 R(aen1604)500 0 R(aen1640)501 0 R(aen1644)502 0 R(aen1652)503 0 R(aen1655)504 0 R(aen1658)505 0 R(aen1661)506 0 R(aen1665)507 0 R(aen1681)508 0 R(aen1702)509 0 R(aen1722)510 0 R(aen174)511 0 R(aen1751)512 0 R(aen1756)513 0 R(aen1768)514 0 R(aen1770)515 0 R(aen1787)516 0 R(aen179)517 0 R(aen1815)518 0 R(aen1820)519 0 R(aen183)520 0 R(aen1840)521 0 R(aen186)522 0 R(aen1910)523 0 R(aen1918)524 0 R(aen1947)525 0 R(aen195)526 0 R(aen1951)527 0 R(aen1964)528 0 R(aen1971)529 0 R(aen1975)530 0 R(aen1980)531 0 R(aen1984)532 0 R(aen199)533 0 R(aen20)534 0 R(aen2000)535 0 R(aen2008)536 0 R(aen2012)537 0 R(aen2015)538 0 R(aen2020)539 0 R(aen2033)540 0 R(aen2047)541 0 R(aen2058)542 0 R(aen2077)543 0 R(aen209)544 0 R(aen2102)545 0 R(aen2118)546 0 R(aen212)547 0 R(aen2129)548 0 R(aen2165)549 0 R(aen2187)550 0 R(aen2234)551 0 R(aen2244)552 0 R(aen2258)553 0 R(aen226)554 0 R(aen2260)555 0 R(aen2275)556 0 R(aen2284)557 0 R(aen2288)558 0 R(aen2304)559 0 R(aen2309)560 0 R(aen2312)561 0 R(aen2317)562 0 R(aen2345)563 0 R(aen248)564 0 R(aen264)565 0 R(aen28)566 0 R(aen280)567 0 R(aen291)568 0 R(aen299)569 0 R(aen311)570 0 R(aen323)571 0 R(aen328)572 0 R(aen336)573 0 R(aen341)574 0 R(aen344)575 0 R(aen356)576 0 R(aen366)577 0 R(aen394)578 0 R(aen4)579 0 R(aen402)580 0 R(aen419)581 0 R(aen426)582 0 R(aen431)583 0 R(aen436)584 0 R(aen457)585 0 R(aen501)586 0 R(aen508)587 0 R(aen528)588 0 R(aen56)589 0 R(aen563)590 0 R(aen583)591 0 R(aen592)592 0 R(aen60)593 0 R(aen603)594 0 R(aen623)595 0 R(aen638)596 0 R(aen652)597 0 R(aen659)598 0 R(aen681)599 0 R(aen74)600 0 R(aen745)601 0 R(aen766)602 0 R(aen788)603 0 R(aen799)604 0 R(aen8)605 0 R(aen80)606 0 R(aen834)607 0 R(aen851)608 0 R(aen862)609 0 R(aen887)610 0 R(aen895)611 0 R(aen899)612 0 R(aen90)613 0 R(aen909)614 0 R(aen912)615 0 R(aen916)616 0 R(aen938)617 0 R(aen992)618 0 R(body.html)619 0 R(cvs-access)620 0 R(domain-security)621 0 R(install)622 0 R(integrate-ms-networks)623 0 R(migration)624 0 R(msdfs)625 0 R(os2)626 0 R(pam)627 0 R(printing)628 0 R(samba-bdc)629 0 R(samba-ldap-howto)630 0 R(samba-pdc)631 0 R(samba-project-documentation)632 0 R(unix-permissions)633 0 R(winbind)634 0 R]>>endobj
+474 0 obj<</D[744 0 R/XYZ null 383 null]>>endobj
+475 0 obj<</D[744 0 R/XYZ null 166 null]>>endobj
+476 0 obj<</D[750 0 R/XYZ null 706 null]>>endobj
+477 0 obj<</D[750 0 R/XYZ null 608 null]>>endobj
+478 0 obj<</D[753 0 R/XYZ null 726 null]>>endobj
+479 0 obj<</D[756 0 R/XYZ null 607 null]>>endobj
+480 0 obj<</D[642 0 R/XYZ null 266 null]>>endobj
+481 0 obj<</D[756 0 R/XYZ null 232 null]>>endobj
+482 0 obj<</D[759 0 R/XYZ null 359 null]>>endobj
+483 0 obj<</D[762 0 R/XYZ null 768 null]>>endobj
+484 0 obj<</D[762 0 R/XYZ null 392 null]>>endobj
+485 0 obj<</D[768 0 R/XYZ null 739 null]>>endobj
+486 0 obj<</D[645 0 R/XYZ null 686 null]>>endobj
+487 0 obj<</D[771 0 R/XYZ null 686 null]>>endobj
+488 0 obj<</D[645 0 R/XYZ null 509 null]>>endobj
+489 0 obj<</D[777 0 R/XYZ null 303 null]>>endobj
+490 0 obj<</D[780 0 R/XYZ null 277 null]>>endobj
+491 0 obj<</D[783 0 R/XYZ null 482 null]>>endobj
+492 0 obj<</D[783 0 R/XYZ null 225 null]>>endobj
+493 0 obj<</D[786 0 R/XYZ null 684 null]>>endobj
+494 0 obj<</D[786 0 R/XYZ null 446 null]>>endobj
+495 0 obj<</D[786 0 R/XYZ null 289 null]>>endobj
+496 0 obj<</D[792 0 R/XYZ null 605 null]>>endobj
+497 0 obj<</D[795 0 R/XYZ null 698 null]>>endobj
+498 0 obj<</D[795 0 R/XYZ null 603 null]>>endobj
+499 0 obj<</D[645 0 R/XYZ null 332 null]>>endobj
+500 0 obj<</D[795 0 R/XYZ null 274 null]>>endobj
+501 0 obj<</D[804 0 R/XYZ null 706 null]>>endobj
+502 0 obj<</D[804 0 R/XYZ null 621 null]>>endobj
+503 0 obj<</D[804 0 R/XYZ null 239 null]>>endobj
+504 0 obj<</D[807 0 R/XYZ null 768 null]>>endobj
+505 0 obj<</D[807 0 R/XYZ null 630 null]>>endobj
+506 0 obj<</D[807 0 R/XYZ null 532 null]>>endobj
+507 0 obj<</D[807 0 R/XYZ null 381 null]>>endobj
+508 0 obj<</D[810 0 R/XYZ null 650 null]>>endobj
+509 0 obj<</D[813 0 R/XYZ null 706 null]>>endobj
+510 0 obj<</D[813 0 R/XYZ null 437 null]>>endobj
+511 0 obj<</D[648 0 R/XYZ null 768 null]>>endobj
+512 0 obj<</D[816 0 R/XYZ null 581 null]>>endobj
+513 0 obj<</D[816 0 R/XYZ null 469 null]>>endobj
+514 0 obj<</D[819 0 R/XYZ null 739 null]>>endobj
+515 0 obj<</D[819 0 R/XYZ null 709 null]>>endobj
+516 0 obj<</D[822 0 R/XYZ null 768 null]>>endobj
+517 0 obj<</D[648 0 R/XYZ null 577 null]>>endobj
+518 0 obj<</D[822 0 R/XYZ null 180 null]>>endobj
+519 0 obj<</D[825 0 R/XYZ null 633 null]>>endobj
+520 0 obj<</D[648 0 R/XYZ null 505 null]>>endobj
+521 0 obj<</D[825 0 R/XYZ null 240 null]>>endobj
+522 0 obj<</D[648 0 R/XYZ null 394 null]>>endobj
+523 0 obj<</D[828 0 R/XYZ null 211 null]>>endobj
+524 0 obj<</D[831 0 R/XYZ null 362 null]>>endobj
+525 0 obj<</D[834 0 R/XYZ null 706 null]>>endobj
+526 0 obj<</D[651 0 R/XYZ null 739 null]>>endobj
+527 0 obj<</D[834 0 R/XYZ null 569 null]>>endobj
+528 0 obj<</D[834 0 R/XYZ null 246 null]>>endobj
+529 0 obj<</D[837 0 R/XYZ null 581 null]>>endobj
+530 0 obj<</D[837 0 R/XYZ null 417 null]>>endobj
+531 0 obj<</D[837 0 R/XYZ null 292 null]>>endobj
+532 0 obj<</D[840 0 R/XYZ null 768 null]>>endobj
+533 0 obj<</D[651 0 R/XYZ null 615 null]>>endobj
+534 0 obj<</D[636 0 R/XYZ null 730 null]>>endobj
+535 0 obj<</D[840 0 R/XYZ null 313 null]>>endobj
+536 0 obj<</D[843 0 R/XYZ null 673 null]>>endobj
+537 0 obj<</D[843 0 R/XYZ null 483 null]>>endobj
+538 0 obj<</D[843 0 R/XYZ null 332 null]>>endobj
+539 0 obj<</D[843 0 R/XYZ null 221 null]>>endobj
+540 0 obj<</D[846 0 R/XYZ null 581 null]>>endobj
+541 0 obj<</D[846 0 R/XYZ null 298 null]>>endobj
+542 0 obj<</D[846 0 R/XYZ null 132 null]>>endobj
+543 0 obj<</D[849 0 R/XYZ null 619 null]>>endobj
+544 0 obj<</D[654 0 R/XYZ null 768 null]>>endobj
+545 0 obj<</D[849 0 R/XYZ null 279 null]>>endobj
+546 0 obj<</D[852 0 R/XYZ null 691 null]>>endobj
+547 0 obj<</D[654 0 R/XYZ null 683 null]>>endobj
+548 0 obj<</D[852 0 R/XYZ null 530 null]>>endobj
+549 0 obj<</D[855 0 R/XYZ null 467 null]>>endobj
+550 0 obj<</D[858 0 R/XYZ null 511 null]>>endobj
+551 0 obj<</D[861 0 R/XYZ null 355 null]>>endobj
+552 0 obj<</D[864 0 R/XYZ null 768 null]>>endobj
+553 0 obj<</D[867 0 R/XYZ null 730 null]>>endobj
+554 0 obj<</D[657 0 R/XYZ null 706 null]>>endobj
+555 0 obj<</D[867 0 R/XYZ null 700 null]>>endobj
+556 0 obj<</D[867 0 R/XYZ null 348 null]>>endobj
+557 0 obj<</D[870 0 R/XYZ null 768 null]>>endobj
+558 0 obj<</D[870 0 R/XYZ null 639 null]>>endobj
+559 0 obj<</D[873 0 R/XYZ null 706 null]>>endobj
+560 0 obj<</D[873 0 R/XYZ null 582 null]>>endobj
+561 0 obj<</D[873 0 R/XYZ null 484 null]>>endobj
+562 0 obj<</D[873 0 R/XYZ null 359 null]>>endobj
+563 0 obj<</D[876 0 R/XYZ null 503 null]>>endobj
+564 0 obj<</D[657 0 R/XYZ null 463 null]>>endobj
+565 0 obj<</D[657 0 R/XYZ null 325 null]>>endobj
+566 0 obj<</D[636 0 R/XYZ null 593 null]>>endobj
+567 0 obj<</D[660 0 R/XYZ null 435 null]>>endobj
+568 0 obj<</D[660 0 R/XYZ null 285 null]>>endobj
+569 0 obj<</D[663 0 R/XYZ null 768 null]>>endobj
+570 0 obj<</D[663 0 R/XYZ null 268 null]>>endobj
+571 0 obj<</D[666 0 R/XYZ null 210 null]>>endobj
+572 0 obj<</D[669 0 R/XYZ null 660 null]>>endobj
+573 0 obj<</D[672 0 R/XYZ null 371 null]>>endobj
+574 0 obj<</D[672 0 R/XYZ null 260 null]>>endobj
+575 0 obj<</D[675 0 R/XYZ null 768 null]>>endobj
+576 0 obj<</D[675 0 R/XYZ null 529 null]>>endobj
+577 0 obj<</D[678 0 R/XYZ null 633 null]>>endobj
+578 0 obj<</D[681 0 R/XYZ null 581 null]>>endobj
+579 0 obj<</D[633 0 R/XYZ null 647 null]>>endobj
+580 0 obj<</D[681 0 R/XYZ null 304 null]>>endobj
+581 0 obj<</D[684 0 R/XYZ null 594 null]>>endobj
+582 0 obj<</D[684 0 R/XYZ null 271 null]>>endobj
+583 0 obj<</D[687 0 R/XYZ null 753 null]>>endobj
+584 0 obj<</D[687 0 R/XYZ null 639 null]>>endobj
+585 0 obj<</D[690 0 R/XYZ null 706 null]>>endobj
+586 0 obj<</D[693 0 R/XYZ null 179 null]>>endobj
+587 0 obj<</D[696 0 R/XYZ null 726 null]>>endobj
+588 0 obj<</D[699 0 R/XYZ null 706 null]>>endobj
+589 0 obj<</D[636 0 R/XYZ null 178 null]>>endobj
+590 0 obj<</D[702 0 R/XYZ null 673 null]>>endobj
+591 0 obj<</D[705 0 R/XYZ null 706 null]>>endobj
+592 0 obj<</D[705 0 R/XYZ null 525 null]>>endobj
+593 0 obj<</D[639 0 R/XYZ null 739 null]>>endobj
+594 0 obj<</D[705 0 R/XYZ null 348 null]>>endobj
+595 0 obj<</D[708 0 R/XYZ null 686 null]>>endobj
+596 0 obj<</D[708 0 R/XYZ null 443 null]>>endobj
+597 0 obj<</D[708 0 R/XYZ null 187 null]>>endobj
+598 0 obj<</D[711 0 R/XYZ null 673 null]>>endobj
+599 0 obj<</D[711 0 R/XYZ null 232 null]>>endobj
+600 0 obj<</D[639 0 R/XYZ null 379 null]>>endobj
+601 0 obj<</D[717 0 R/XYZ null 594 null]>>endobj
+602 0 obj<</D[720 0 R/XYZ null 730 null]>>endobj
+603 0 obj<</D[720 0 R/XYZ null 302 null]>>endobj
+604 0 obj<</D[723 0 R/XYZ null 693 null]>>endobj
+605 0 obj<</D[633 0 R/XYZ null 616 null]>>endobj
+606 0 obj<</D[639 0 R/XYZ null 268 null]>>endobj
+607 0 obj<</D[726 0 R/XYZ null 450 null]>>endobj
+608 0 obj<</D[729 0 R/XYZ null 686 null]>>endobj
+609 0 obj<</D[729 0 R/XYZ null 302 null]>>endobj
+610 0 obj<</D[732 0 R/XYZ null 686 null]>>endobj
+611 0 obj<</D[732 0 R/XYZ null 496 null]>>endobj
+612 0 obj<</D[732 0 R/XYZ null 385 null]>>endobj
+613 0 obj<</D[642 0 R/XYZ null 768 null]>>endobj
+614 0 obj<</D[732 0 R/XYZ null 247 null]>>endobj
+615 0 obj<</D[732 0 R/XYZ null 149 null]>>endobj
+616 0 obj<</D[735 0 R/XYZ null 713 null]>>endobj
+617 0 obj<</D[738 0 R/XYZ null 768 null]>>endobj
+618 0 obj<</D[741 0 R/XYZ null 730 null]>>endobj
+619 0 obj<</D[639 0 R/XYZ null 698 null]>>endobj
+620 0 obj<</D[873 0 R/XYZ null 798 null]>>endobj
+621 0 obj<</D[741 0 R/XYZ null 798 null]>>endobj
+622 0 obj<</D[636 0 R/XYZ null 798 null]>>endobj
+623 0 obj<</D[657 0 R/XYZ null 798 null]>>endobj
+624 0 obj<</D[738 0 R/XYZ null 768 null]>>endobj
+625 0 obj<</D[699 0 R/XYZ null 798 null]>>endobj
+626 0 obj<</D[867 0 R/XYZ null 798 null]>>endobj
+627 0 obj<</D[690 0 R/XYZ null 798 null]>>endobj
+628 0 obj<</D[720 0 R/XYZ null 798 null]>>endobj
+629 0 obj<</D[804 0 R/XYZ null 798 null]>>endobj
+630 0 obj<</D[813 0 R/XYZ null 798 null]>>endobj
+631 0 obj<</D[750 0 R/XYZ null 798 null]>>endobj
+632 0 obj<</D[633 0 R/XYZ null 753 null]>>endobj
+633 0 obj<</D[705 0 R/XYZ null 798 null]>>endobj
+634 0 obj<</D[834 0 R/XYZ null 798 null]>>endobj
+635 0 obj<</Type/Pages/MediaBox[0 0 595 792]/Count 86/Kids[636 0 R
+882 0 R
+885 0 R
+888 0 R
+891 0 R
+639 0 R
+642 0 R
+645 0 R
+648 0 R
+651 0 R
+654 0 R
+657 0 R
+660 0 R
+663 0 R
+666 0 R
+669 0 R
+672 0 R
+675 0 R
+678 0 R
+681 0 R
+684 0 R
+687 0 R
+690 0 R
+693 0 R
+696 0 R
+699 0 R
+702 0 R
+705 0 R
+708 0 R
+711 0 R
+714 0 R
+717 0 R
+720 0 R
+723 0 R
+726 0 R
+729 0 R
+732 0 R
+735 0 R
+738 0 R
+741 0 R
+744 0 R
+747 0 R
+750 0 R
+753 0 R
+756 0 R
+759 0 R
+762 0 R
+765 0 R
+768 0 R
+771 0 R
+774 0 R
+777 0 R
+780 0 R
+783 0 R
+786 0 R
+789 0 R
+792 0 R
+795 0 R
798 0 R
801 0 R
804 0 R
@@ -1179,125 +997,41 @@
873 0 R
876 0 R
879 0 R
-882 0 R
-885 0 R
-888 0 R
-891 0 R
-894 0 R
-897 0 R
-900 0 R
-903 0 R
-906 0 R
-909 0 R
-912 0 R
-915 0 R
-918 0 R
-921 0 R
-924 0 R
-927 0 R
-930 0 R
-933 0 R
-936 0 R
-939 0 R
-942 0 R
-945 0 R
-948 0 R
-951 0 R
-954 0 R
-957 0 R
-960 0 R
-963 0 R
-966 0 R
-969 0 R
-972 0 R
-975 0 R
-978 0 R
-981 0 R
-984 0 R
-987 0 R
-990 0 R
-993 0 R
-996 0 R
-999 0 R
-1002 0 R
-1005 0 R
-1008 0 R
-1011 0 R
-1014 0 R
-1017 0 R
-1020 0 R
-1023 0 R
-1026 0 R
-1029 0 R
-1032 0 R
-1035 0 R
-1038 0 R
-1041 0 R
-1044 0 R
-1047 0 R
-1050 0 R
-1053 0 R
-1056 0 R
-1059 0 R
-1062 0 R
-1065 0 R
-1068 0 R
-1071 0 R
-1074 0 R
-1077 0 R
-1080 0 R
-1083 0 R
-1086 0 R
-1089 0 R
-1092 0 R
-1095 0 R
-1098 0 R
-1101 0 R
-1104 0 R
-1107 0 R
-1110 0 R
-1113 0 R
-1116 0 R
-1119 0 R
-1122 0 R
-1125 0 R
-1128 0 R
-1131 0 R
-1134 0 R
-1137 0 R
]>>endobj
-795 0 obj<</Type/Page/Parent 794 0 R/Contents 796 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 19 0 R>>endobj
-796 0 obj<</Length 797 0 R/Filter/FlateDecode>>stream
-x}SMsÚ0½ó+vr"3‰±lc§’¤¥IÚ8ÓK.²-°©mQI.åß÷I6Ði‡Á kwõ¾ôsÀÈLJÑ$ 0¦¬Ü&ƒÑ‡
-|JV؉È’œ|Ï÷ñ&>Í?ßÎi©äFd†îeÖÖ¢1Ü”²¹L6®•¡Ã¶^O|oŠæ¾'¼¶%ÑxÌ°M'øà«­º0öâó3TÑMìFqÍSmÏL"&ÆzÁÔ ,ˆ® =osnDWõ5CšQR´4o×ÄÆÄ‚Y4Ecº»O ‚Øj bÏ*1LŠRS*åÂ/§LV”
-¥.òæ%¬*@XP-¡ˆ&0鞃A{vçÒë‰ÙÇ·Å€1+CÄ"È_SÀ&ÖC·ªèÉfÇÇr|æÍ¿‘ÂgÙ69¥£h'ÏPkÆlg£Ñn·ó´Гj=z[ël-8:þo¢xA[¾๬ׂ´À­3rÉ#=Š|†´Õ4q¼ÜâÀä/`àæ¨>½¡ÔþÝ+Ì ôÜû³dq—Ǧ)/‘áÞ"<P¨ÉâË3-D#¯hÙ¦U™ÑC Ó@ëe¸X>¼\Ò«}(Ï‘ÉíÞ¦!ëÏ=„Í®‡•MVµ6¦»ÒNÂ.¬Z¶*G,HÅq¨MÑ«²¹®J$Œ»K×_ë0šºh0\ïºÕ £›³°œ˜¿Ò+g}ZÖÛÊ3¿Ýq.
-<_‘3§7ûëà0c¸endstream
-endobj
-797 0 obj
+636 0 obj<</Type/Page/Parent 635 0 R/Contents 637 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 19 0 R>>endobj
+637 0 obj<</Length 638 0 R/Filter/FlateDecode>>stream
+x}SMsÚ0½ó+vr"3‰±lÇN%iK;“4´8ÓK.²-ÀÔ¶\I.åß÷I6Ði‡Á kwõ¾ôsÀÈLJÑ8 0¦¬Ü%ƒÑÇ[
+|JV؉È’œ|Ï÷ñ&.gw3Z(¹™¡÷2k+Qn
+Y_&[×ÊÐa[¯Ç¾7Asß“^Ù’É
+Õ‚¡4ÀeXV¼€UEí%8¿’PD‰  ˜tÏÁ€ =»ó é€õÄìãÛ|À˜•!bä¯(`cë¡[•´´Ùñ±¼9óæÀßHá³lëœÀÒQ´“g¨5 7Æ4ÓÑh·ÛyÚ
+èIµ½­u ¶ÿ‹7Q¼ †¯x.JÁµ -p`ë̇\òH"Ÿ!m/·80ù ¸ùªOïÃV(µ÷
+ó(=÷þ,DYÜå±iÊ d¸€·êc2ÿòLsQ ÅKZ´iYdôPÀ4ÐzÎ/—ôj_
+endobj
+638 0 obj
652
endobj
-798 0 obj<</Type/Page/Parent 794 0 R/Contents 799 0 R/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>>>>/Annots 22 0 R>>endobj
-799 0 obj<</Length 800 0 R/Filter/FlateDecode>>stream
+639 0 obj<</Type/Page/Parent 635 0 R/Contents 640 0 R/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>>>>/Annots 22 0 R>>endobj
+640 0 obj<</Length 641 0 R/Filter/FlateDecode>>stream
xV]sÛ6|ׯ¸¦‰:cS¢>,Éov§NóÐfë¥ Š¨H€À(šéïÞ‘´å4êÔeK{»{ þ5JiŠŸ”V3šßPVî·£ÉÆfSÚøæfµ¦mNÓd:Å'Ùø§R5Q{JúÅ):zoCTUEÊæ´Õ!Òãݯ÷w?nÿ”:颫s=O“*Ó[£nhzKµÊ)–šje©Q{º} JÓ~ßlÅ»¶çk(7!z³k£ÎéhbÙI™³QKT¹ÈÔ]´[8œ¢"h©«†ïu¤“k ð=*%Dï þ€!Lé:w€sgßF:Xt[v{Fý„˜ñ[ŠþD\­ciìž*sз]/`÷©—›täã¨û*í¿[®¹f¨wy²¦¿©v^˺Ÿ·#¦_4
&ê+¡é%.¿§1•16·“ÉñxLïHœßóÚmHCXŽ¿´\ÌñºX¯ð:Ã/N/öYN7¢Æ³a§ÞGé-Ý·¦Ê™wöÒ½±Ê›ËVr”³L¸¢ÂxÖ·Ðïö^Õ½8ËAœdcfßözLfÇ°–ì숄/½Î¢ó§„¶¨O¡tm•“j£cj3Œ \òTM|6ZÇ/d`zröØ„¦Â)D]'½=©TŸ4µ¶ ­ªˆ¬Öy`VÌ\«\J}u>ûŠ½sñû/mxÞéõµÌIW`hc1ë=ÜQ‡S‚Ötäá
Î ¹†]NGk«v•Æxm¤þ¬³–Ûz´ZôE,2ÖÆ2j‘c×; ¡6Ódâ[hÑf°z@tÔ©ào
w¢BLøïøØ.k)­‘šÿ¬›…ÜIçÁ:ïƒuvË#K|¹›ºq>*‹)ÇÕýoQå’¾‹(ŒÄ^wiÔ"^ ³’ßú «P‘€EÔ€Äìyʽ±Ù …h궒ìK莂L³çÇ ¶
endobj
-800 0 obj
+641 0 obj
1091
endobj
-801 0 obj<</Type/Page/Parent 794 0 R/Contents 802 0 R/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>>>>>>endobj
-802 0 obj<</Length 803 0 R/Filter/FlateDecode>>stream
+642 0 obj<</Type/Page/Parent 635 0 R/Contents 643 0 R/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>>>>>>endobj
+643 0 obj<</Length 644 0 R/Filter/FlateDecode>>stream
xV]oÓH}ï¯¸Ë A¢ÎG“4©´ÀªÛ¦ÚEtµÛc{¨=fÆ-ù÷{îŒÝÓò° BZ_ßÏsνߎ¦4Áß)ÎèdIYsôrsôzs4IV+ÚØ?Lh¾^&+š¯Nñý”¿ZIl'ðqÿÑÙ.WëdÞÙÎ`Lá|üfMÓ9m
„].É’6yx{B›l4Mæ ]z¹¥“3ze¥ð’|%É5)eFªl­ðÊh*T-“g›¯p8§é4:<žÂÝhSI„øçD³­å¯:R:x–߃‰#rmš++3o쮚+ç­J[™Ð9lÊR:O;Ó¢"‘³‹†³˜Ðñô$™qô ‹¶®wäL0Ì„&'%Uæ.„4[vç¨4äM)áÂr<ÚZ‘y•It
¿»Æ N¥á¹‰B'RƒŠÌZ«<4Ez๠œ%u$"W±âÿÂIp¡`XBa¸“µÔCd\}8ÿûßËׯ®.Î7Ÿ9!Ÿ þ:™­ïµþ1ýž­‡ê½èÔ{~F›N'm§BqNUäñ ø ʹç(<PôÜ?…>7[c½
v°:6hU#à\ä·>¥ !
endobj
-803 0 obj
+644 0 obj
1435
endobj
-804 0 obj<</Type/Page/Parent 794 0 R/Contents 805 0 R/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>>>>>>endobj
-805 0 obj<</Length 806 0 R/Filter/FlateDecode>>stream
+645 0 obj<</Type/Page/Parent 635 0 R/Contents 646 0 R/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>>>>>>endobj
+646 0 obj<</Length 647 0 R/Filter/FlateDecode>>stream
x•WaOã8ýί¸×ÕÒ´iK[¸O¬v¹Cºe9èiµÒJ'7qZC÷l‡¶ÿþÞØM[²ôX@
E±Çã÷Þ¼™þ{S¿1zÔRR}˜}šu£ñ˜v3Ã?]÷¢1 Æ#| ¢I–â¿áîM¿ ÄÂKÄß>§suNñ€&ŽŽñ!õï»4IZq4Œâˆî\Й¸Àaœ*g”]*¥K£D—Ù»ÉÃQçj@qâ´{#ÄiÝ|™|ú&sd¥ó\/yçRå9M%¥*ˤ‘¥#•­uE••ts}OÚðŸ÷ä4YgÔ´r2%+Í“J¤¥B,lÄ'v©ÝâÖ8éO­I8Žc(d}6­ŽtI§Þý<ÓVDôuŽ}ÊR*3\(å( mÅýóŽK]gTj7çä÷–‘›Ë’DŠ ”c#r“UÜzœ6Ù‹pb¼‡Í&g 7UÚ¶­-©>íyz{´ªP¹0ùP¬uªtáa³s]å)ÍÅ“$Q5kŸÌë'—¶Žtðܹr$Sõ?Ð’A é
á…) ‚³Y®ý2P_J,.×à‹
@@ -1306,1108 +1040,827 @@ E±Çã÷Þ¼™þ{S¿1zÔRR}˜}šu£ñ˜v3Ã?]÷¢1 Æ#| ¢I–â¿áîM¿ ÄÂKÄß>§suNñ€&Ž
sWÓ–»0\íR±ŸÍšÃT¯¦¦]æM)œz’ä¡ò2…ºÀ!¥Bº|ž9Ï¡§À0jÖü` övíóÀÀá͈¸áó… m£k
Ð=1Ð̘€p|íÞ{ùÓá_ÏókmŒáõ^þËqhÍóù-ùpCoôÂâœÞ²×SºÙ»›XwÝÚK÷
endobj
-806 0 obj
+647 0 obj
1365
endobj
-807 0 obj<</Type/Page/Parent 794 0 R/Contents 808 0 R/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>>>>>>endobj
-808 0 obj<</Length 809 0 R/Filter/FlateDecode>>stream
-x­VaOãFýί˜J­$â$&$!*ÝwÒIwÐ6nQÕôÃÆ^'Kì]Ÿw äß÷Í®]BôC v=óÞÌ{³ûídDC|hÓù„Òòä}r2ø4¦Ñˆ’+“Ù”’Œ†Ñp8¤$í%†¶ª(H9²Rg$ÂG«ÖZä ¹¤ª6©´VZ:Mîî¢ ×#]®²ð¿.EÂì³ÇÛ"Þ2¤~<‰Æ@Ô»¾I>ÎésN;ÓPc¥O¼øý×1Y·+$)ÍwÖÉ’—4ù¥ØQ¡¶Øm¨0fKÂñjH:´¬û£ó(æ,òQ”U!íÀÞ×ã¾u¢vMuHÀ¦µªÇP)z!Ê• é•öAŽ
--Öx µ±´ìÙ&Ý°­2»ä·ùízyÚAêôÚ*5ݱ"}M…¼—¤M­Ü.¨”ÕÌ"Í\(=Õò[#­C{©Ö>˜:Ü
-ñØå)gi]6¾¸Ä¸xÛeãøNÜr£hÖºl\–­!7ë“r­[-„Âí5VxãÉUƒµóÕ@0•¾n°dW©TÐÿSCãΣû¡B¢Î¢=TŽM ð{ìa6$?sn8ABOÜ_¥1ìŠ& žFøK³íédõŠ—9ôà_ŽˆaÑùEhv±çëSoĽ„Üà
-Ùœ–ø
-ó‚åžá·ö}íuƒ‘T5tÌ€ÿCQ¹ÑœŽqTÆÏÌ¿§Æ®õo³ô(q~Ò+?èFd!WµpòŒ [™Ã4´jÖ¸ŒT¦vßíig‚™ø¢tfíÔM¦_#qKÜ»..Þ}}ÿŽ~®Í\FW&mJÜ+ŽƒCüV?¼ÖûÏ·›ñl]âÖŠ[͸ÿËÉß°œ6‚endstream
+648 0 obj<</Type/Page/Parent 635 0 R/Contents 649 0 R/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>>>>>>endobj
+649 0 obj<</Length 650 0 R/Filter/FlateDecode>>stream
+x­V]OëF}çWL¥V q’‡J÷SºÒ½Ð6iQÕôaco’%ö®ïîÈ¿¿gvíKH€>´ ÀÁöÌ™3çÌìדõñ= qJç#ÊÊ“·ó“ÞÇ! 4_áÎh2¦yNý¤ßïÓ<ëÌ mUQòä¤ÎIÄN­µ(ÈòI•5™tN::ß"ÜE®Cº\æñmŠ „9xÎ?–ð#}ꦣdD«ëù‡)}ZÑÎÔT;Ïþü}HÎï
+IJ3Äó²ä[šÂƒ¥ØQ¡¶xÚPaÌ–„ç»1=xhªîΓ”³ÈQV…t=wg‡]ç…õuuX€Ë¬ªÇP)z&Ê¥ Ò+AŽ$Ôða~6it>JF4œŒqâÇJZEò/i€
+ùý4™<¡ŒšyYÑhJsËÅ8¯ô:Tï6‚sq'T!–àÀh.ÚZeï¤=ª2åÞv~lØ´]ûY¡¤öÔýÜÜ;oï…€ã¼eC[ÛɽæüÅYÝÆÔENkéi)2PÀ’YáÎ1Ј4MÚ¾æFÿ¤É™Rú —ªˆÍŒµ2óÅ®‘EÛ0'Ñ „èÊx–Dh/^àwMN™Ð$
+gh)Y39÷ÌII÷ü`ƒŠ€í)‡
+±ôYè/B‹5.#;î õ¢ãêlCÂÑÍêf½8=Tl£Õlc äŠô–
+y' Èj«ü.ê”õÌ2])ø"–eå×Z:S%œ»76G+¸ÐÚ=»’ÕÀQÅÊÀÊ µâö3v‹%E…´ í
endobj
-809 0 obj
+650 0 obj
1189
endobj
-810 0 obj<</Type/Page/Parent 794 0 R/Contents 811 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-811 0 obj<</Length 812 0 R/Filter/FlateDecode>>stream
-xWÛnÛ8}ÏW òpT_â\
-,Îma qÓÚ c¼Pm³¡HW¤âøï{†”GmÑEÀ‘HΙ3gÎÐßúÔÃOŸÎ4<¥¬8¸œ|¼½ þ Í—xszŽ9õ’^¯Gó¬ÓOú½„kái²¤ùZ™•£kkŽ<-lùô÷‡ù7ì?¡~?î?œakõ¼š¶XæH˜œv¶"çEéÉ[â—Ot¸][Ú–ÖKâ'Ž6JK²Kò¥pëC<“†&äªÕJ:NÈ-‘X e豃³FŽûÃdÀáÛÇä•ÖaS&tA¹Ýš¤^98M8ÑÎœ0°B­ÖžJ)rJKÆq=ÿ3ý<›ÌÿâC
-üŠnÇ_fƒ·‰R‡q¾Êž"`_îÂ!…Pš)Ð
-ØmÙiäÖ­J[m‚¶ö‰ Ÿÿõf|}CK[R.=Žpš‰"´ŽR È $ˤsËJëv‚W­eN¨“_ÛÊÇ<:å¥kFEt¾U¹ì’³Tˆ]Š¤œ-¤5’¤v2„Y«ÀwI›Ò¦Z!ŽoŸe™a5)ŸÐà ³•Î‰„Æivs‹Å¢•‘pá]& ¥\)ç*PòÇ çŠ Ý®Ò¢©ÒR½„ãLw7ãÙ 9 y'AÕ&H:Š ™å6«
-i¼ðʲ\À«³U™I
-@ Iá”,â 7óô gÐÔÉù>ð e,Ûíur1LNn°~B×J¬Œu,—‡Hx(Û¯{‹•·Ï(A,|L­&™3]+de¾·èøП÷’fðo:1–®yrUšê‡ŠÔ‰žŒFÉùŸp#¶|d
-æX8»¿d!ÅÅì!…0(´ZfÞáÔª,Ñ¡ ½®º«6G£.Á»ÙÙ®>½é†¿wÿκt7žÞ§ýn‹ÐøÃÙOçý¶“¿‚eœ‡¤-÷}!^TQoÁh €SŽÉ½öÑ~5÷;ˆÇ‹S¾ªbõô@4®ØOF“òtã’2­Ïÿâ›-•ß½šx;“‰!«sYìØACÁHã”`UÂÖ£E,mU{–‘<1DìpÖ)SÊdFÄZ*š$#RfÝÛ¿ArA’…u\±0ŽàË2‡CzÆn±×9̽'‰á0Æu½ßYaÞ›¦œŠ5z׊[JLSÃÊù3zS¬`NpM‘W fð©Ë*˜0šý{±\¬Pbédù wLg,àp=”·'e˜È(X£Ý.#ù<§ ¾Ñ ÕŸ˜ò¡ÚP0æ$À¾ÐÛ¯!@ r#›é´ÒDý‹.qçʬí™Êas
-øEÇýuHÑ?X¥!篭–#“·Çrn5
-ó׈ž)$mÙe g#
-ä°U~]ÇÐ
-½ê0IåêûZ´qQ›ñtŽ:•„/F|‘©n.`3/ MG=v°
-pM%˜4T™ÑÌX}j§7ÅíñÍßzvS*x÷÷JV\|ö‘†JnŠ0Âß4Ý5úöüêáãäP^nÃf5ÅoU** È*¡[` ¨Å¦âíPKÒSLY©ö¹|`@)ö„‹#dö+àÖ´"‡@n‡[p﬛Ž•]"E¿‰¨õ´Zªê©=ýævr^_ú§g 1À½opÏÆ÷—cvúo°jÜü÷îR ë8î:ŽÛþ××…“ó^r¯¸}øàûrðìñrendstream
-endobj
-812 0 obj
-1505
-endobj
-813 0 obj<</Type/Page/Parent 794 0 R/Contents 814 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-814 0 obj<</Length 815 0 R/Filter/FlateDecode>>stream
-x•WÛnÛ8}ÏW ò²)hm'q’‡>äV Ø6é&n»‚.h‰ªÙJ¢JRqõ÷{fH9®ÒÅbQP,q.gΙ~ß™Òÿ¦t2£Ã9åõÎÅbç÷Wg4=¢E‰7óS<4É&“ -ò½i6dG½s¦ ¦ùB¥³5½¿yýKŠ.+£›@ï._,¾ÂÐM§ÑÐÁì†ö–:¯ñaË´£°RŒ'õ¨L¥–•¦G£ðÞ×˃¥òº òÚ=âKñ¤¨kÌZY¨·­MUQ£ñÜç¶n ,„•f÷:˜f3v kyŒ¬uö‹SuFŸp6›Ó¦ñAÁ~$Ÿ;Ó¢]”Hw3ºÓ
-^ð’?t]ŒmðÌ‘Ê'TZGµucß…HÍg”bšÍ3Æto±ÒÆzåºûO÷ȇ $÷‚Maµ§ºËW#S5'ÈÐ爉þ3ßûÇŒ^àÐÀeã·#õ»¿^ì ”t|vˆŽNOð<ÃÄQŽ+||–ÍŸ×þ8£76ÿÿÿRáÛåuZÑze´·µ¦F¹Bå=g;.3¯¢!‰ ÅúØ °¶ú§l9|ì5_j¢V;`_‹eÏ@¾½HœÉ SiØ»NçÖƒ¥ÝIbÀ
-vÆLÙ-tÓƒ…ö»øLç¬|«sS]<ó[J¬[`Ûclî~Ê
-:Ì=dQ@#ïY8
-½ôD…)Kp zíüœ}:ñÑ4òÍèƒvŒö„ GÝ«z©h©²_f´R(ŽC
-,;4gÛ¨`ð;•yª‡½‡Q« eе°•¿6u[隃‚Q9OŠ2Teä{©ÃZ—§\b4±:ˆ{±B¾¹‚Ž- :”]UõЀƒá@E‡à,€$ª‚3å‘d$†—XÀ¡^¥ÊÃȬ%˜RÀ¥ð$ø!¼H,éZö:û|8#t…ÙçùÑ>-X¹h XbÝÞK<#ÏÒè’Dp9ù®m­ ~Ë
-/žØÕ4£{à+Tg0Zë½a©!’A•|É:‰¼vú{§ý8mµ´(e4
- ¡îÌ\錧M=rí÷áÀÆwð„
-T/ˆù‹ÇRIô²a„¸0d-½ÒA#nðTðcæ@ƒŒŸp¾êQ‹"ÕÐKR#4Y³©6R.©ëV  ÿJµ¨l©äy€9….wQÿ“FeŸb&+¤3hȼ IÐS3òž,ˆ<‡ ÏaÛ®“:ÀÈ@b è™òhf’@_«þ’Ð_
-™W¢&žUÍs]U°Í­Ñ`—W®ùW¼Ls€& •uÁ«`Þ¢ ‚¯Õ7Ð1ŽÉscÀÇ h™ÌÓ¤1~äL2è¸ì ¥ÃqÑC×¥ê*t‘H ‘*;Þ ¸äyÍÛ†þÑV&7R8ÿ 1³)[1¥}ZvPpÉÛÍÈ»× ‰”}“ÓKêãli(_Ö¡§¬#†]þÁ€g« ïF\FÙL
-ãe/CQ<±n%qb°—ÝáÕKtc¬LÒ›Q]LteácÀêr¬P7æ‚7žÂ6¿…¡ÓmÒ‘ã ûHôaÏóJÄL(°ú‡`R“„˜coLÅ(¥¢^:× £`o­#ŒY "}ù« ͤ[t 8EN·Œ¹€,ÒüÏ+ªo--8ÀAl/Òóh¤0jË,
-endobj
-815 0 obj
-1723
-endobj
-816 0 obj<</Type/Page/Parent 794 0 R/Contents 817 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-817 0 obj<</Length 818 0 R/Filter/FlateDecode>>stream
-x•VMoÛF½ûW |iÄ”DÉ’ Å–¶äšLÓ éaE.Å­É]v—´¢ß7KÒqØ @að´³óñæ½™ýûdBcüLhÒtNIyò>>YÅ'ãà₾ÿ±{|S¸X!Í.ø6 fd%e|‡póü棛K
-Çgð>_\Pœús|“¼ºÊEUKKa@×JìµqJïéhKN”;ANÚ'i_Ç°›É¬us6 zœ¾
-ƒI@k][“6I­Œn-g4™t–á‚íâ\9ÊT!)1ºJ;T(W“ɨ–®v”¡©’63¶¤ÚГ(T*jÙ&½HAk…3¸\íåC.jªsÉ)Œél2mS,Ô£,ŽpÝ8é£å’*kv…, I©ŒTM™Pð"ô‘Œî­`îjY9Äò6•pN¨(8
-NÛ¼ñ¿fðÅnÅ®828ûÈ°fJË ; çè€ù‚ª]nš"¥ÔÐòö–}·žßÒþ“±)Z«ƒF.”‹'XX%SÆ(VfMÁæÆpV9
-0€³]ŽFãõKD%vªPµB]h³ÊØiU
-[¨ÞÃ0m ÂýrR§TJ
-‹ÔßðÉkÄMQ˜×ÀÔ`(¾D¦ ˜ì1E€A¾P|}‡æ4¶²ÊqÆ`Q`/®â–m“ñ9{é|<Þ­\BH¦WËKRÏæ—Áüu„t±t®)+æ¶ãtF7ÿ"÷Z{R0“ûÞ!°¥4 “/ZÐK£oEÔ߯?D«‡ßV!A÷WýÉòêv½ÚÄ´3uŽž  `T÷Ö4Å«(þð°ýtÏÜð’è"s2ptm£5·å tj¢±¾-ÞÃ׈ €I"u VP¯e³T‰5ÎdPYRTyˆä`šµz‚ÐÞ´@àR¹M}ðÏ]ðËsBøþ
-üúê3Š/Ægƒ¨‘Ÿ@__)·:îƒ**U!¬¯˜1uˆZ0Y×nèâG¼¸SÚ|µ@ïpÌO`6d ÆåëÓ̕»
-SáwN¦5u]75ÖeuÐDä‘'Òøû/»‹<´hwän·²Œÿd¨ý–nÆtÉãvBgáy;Wþ@„?û¨Ø<kÐڲ促ÞÊÊXa~(;ZV”xG#xY)RLI ”wt”Mœq
-óvðÆWÑÊÓ3¢e}º[x­·¬›1¤¶} Ûe êooÆ-ïÞ/)ú´ŽWE[Ø_mïî–›ë¨Ï¡éÑÇíç ]¯¯i³iõû:Ši½¡Õò’yè£ô·úQ{_HùX–¢®Ó ”Á•Ö‚”¥tNìA¦ËŒöÓŸÃ&8~ØZ5/–ž§,·D—)7:ÃÄÖ)`cçÝ$Ë”ÅÜKr™<>{¢õ=yöYéLÑø,á41Õ¸ïdMMÜ¿¥;ž`¶sos$ëdä½<y¢¶ ¸2
-RàÂ}”vÁw… ·¼I°‰ä7,ç¡^–X¸ØJíì‡b?Û®7Q÷R ‘$@Ñ‹pXEÕ6àE¹ =Ê©W{…‘TÑS½Íå4Ò‡OS¼"°3¾1µžb¸Ûñ&9 Ç¼;`~ý˜;åMS ¼/z¿§¯[“é¼üï51‡^NßQa0El~Ät©Oñ¶â·Ñ”_G|@>ùùê` RŽ5#ê:ä*É[–à«n£õÙzÞðPõ¼eEójýIYž¸ØÃS¨>3š;LKán¢ñ#-Sûƶ#Ù¿Û
-endobj
-818 0 obj
-1398
-endobj
-819 0 obj<</Type/Page/Parent 794 0 R/Contents 820 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-820 0 obj<</Length 821 0 R/Filter/FlateDecode>>stream
-x½WMOãH½ó+J¾lF‡„
-^ÌLD²{åuºPb€k `
-4 u^[÷Œvh bÁW?Zÿ©Ön¥jOÉ–àÏ¢;–¤ÒµP]¾M*˜{ÁÀ©ZvÌ øs4¿¦£Sçk••Ü{K§ÊøéŸî¨=;½Ø Ø/¨=›žB¿†Ô>é¨}ÂÖö%ìWÔ†~…úÓÑÝ>Å;ìÌ{´S‘Qhú ÉQjõ‚Š)n>¿A‡Y'*}~×oØ£CSö‚˜6è#[úmË”ºRÕèMT „‘†/ï-Ikj4¼45
-Ùµé BMê¦zÊtµ–FA†Z°ÃGT -!:Ô ý!³Y¾Yr§pG€äÂBf¼ˆéz¥Óçïu§DŽÞÝÙzI’ùR+WFÂËF—µuʤrYpOUÛ>fiÉA
-HHüwé îÈTï2ô¿•¶õ¨ ´Ì§s˜üoeZÊT&Y¯)<
- ÂŽ´¯úÿªÕd˜ƒ8w“…iú¾À:3<REÎeÖ¾–¸ØþܾB)S@Nˆ^QÊE Øý°S»`ƒ(îÎr~ˆ,1Öyq`1:˜àìßÝ>.nîyž`ÖteÄaþLG*ú=¶Z€Õíc|%{5¨t<ùíë!Y#LOø‰)Îï ËĉæFk«àÊ
-t½ø2:¯TJtªPgB«¾iú}@x>U¥n@™§¨¿0Cõ“nà8WÒâ£Ð¥L&ÉDo .È<nkÖ £ü²ð¶+˜w,Ãêyõd|ú Ío¡!ñb|à=0‹™È`¾€]¶…
-endobj
-821 0 obj
-1601
-endobj
-822 0 obj<</Type/Page/Parent 794 0 R/Contents 823 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-823 0 obj<</Length 824 0 R/Filter/FlateDecode>>stream
-xWÛNI}ç+jy¬`ð ï·¬â ÖJ+!¡ž™¶Ý¡§ÛéîÁñßï©îÛ˜„]EAÁž©Ë9§NU¾t©ƒ?]õ¨?¤¢:¸šœ}P·KÓ¾^ŒhZR'ët:4-Žo,Ý™Rí%……¤Ã\™’” ÒÍD!=Y£×‡´NTÒj!¤µ­©kZ)¿ `7¯{QåO{¿²®¤b!Ì\~˜~;èÐi·Ÿõúq•Va}B¶ 竼ÐJšƒ)K*
-àIÛBhòÒ½¨BÒ /ÔBNz«ë ¬á8üqz?¯]±Ÿµ°ÆÈ‚÷=ßÛ ÿø—r¦
-W Ýؼ
-è[k26ÐÚ®h'8 ÷zÖÖ.sQ<“(KèS€í¨hÖ[k?dÍK½a6` .‘
-ÕZ–¿¹Ja0…¬Ù8D<Ó2š_Ëü^mIä»ÃÇHh僌£Ì~[.ÛiíWþÅ@YÉ2–ÎBã˜[T 2@Ê5ó«j‰o`¹q\ ˜áøÔÆñyDL[J4´9[OZ°èD ?F"®˜\(HŒ¨5ò”ß$_8µdHQ| `ã;5_„í¦ÁРk.>ºõŸ]!ö‡,Á÷…Øï§ÅóZˆçÏ!Ä”8!É…¤ÇΛ=züJ–—ןînï§tôûÑÛh™ÿD¤“k¿+Ô¨Bz«»hÚŽÞΊ½¤¡dr j™·÷¤´™î¨·ôlôTYÆO04‡yrŽ¸UÓz!^9kæYìË»ÝI(¯í¶´2掋øEÒ‹tsÿÀ±Ìæ x=ˆ;­4#r‹W,a—Ö^oŒø>­Ýñy6|uÊ°¿ Z‡o‰ø©¿üšÖ’zï:e½…Kd}ƒ“vkJœAø,Ézé䋲5~aßËkìŠíÃð†Mìl’t?®Qk¼Ðºþ³½etI¦®r¸¨»—!WÖŸM¯'
-sÎ)yU)-g`@|_Ó5»é4(›ááµÂ{<0ÿÁôï" 
-à‹:Ø
-[ +>†•¯2ºcKƒx¢Kò6œÈKé (œÁ›s|{‰’]ÆkW™=dp¥‹
-­Á»k°¶fk©9ß3Èàv|æd+©è°5iÒÏ>^4×…³vi8ꤣ=n[š8û  ÝØ¢Þì®æ4=~:êá?åñ›M?¸èdcønÌÏãŽøëà_=0endstream
-endobj
-824 0 obj
-1469
-endobj
-825 0 obj<</Type/Page/Parent 794 0 R/Contents 826 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-826 0 obj<</Length 827 0 R/Filter/FlateDecode>>stream
-x}VaoÛ6ýž_q00Ìý`9vÛ-ºM–ùÐ6KÜò…’(‹Dj¢dÇÿ~ï(R–Ýn-¤6É{wïÝ»ûçbF—ø;£Õœ®–””7›‹é§Íf´ÉðÍr½¢MJ—Ñåå%m’ñ}FÓÖôpKB§de½“5‰Zê_2šš\’%~´±– ÿ_ó Ú«¢ -eJ¡ÖJwrrC¦jß3x˧¸6"M„mÞl¾_\ÒdvÍa,Ò´–ÖòQŽÒä3÷ûíõ#i¾Œ|i“+ܶé
-1‘ iÓPbêZ&MDÏãG™!s€ÙÜ=m芿–örlvòùu·¹@i9¿²Åz…ßçø‡‡³®èoiÈ\ôëõÛhyRöyt­"Úp"+2äh2gŽÆmWþÄ”%sÓ»öTŽm'…’º¡éôæþ§»Ç¿î§›Ï§Ï#útÙÜ´EJ\]M±$®¬°—ÐM•°voêÔ>KÚ_ ‡£+‘$¦
-—µ0Û-ÞUÚóÚjõJ±yaMQ'8Ú \á•M¢ ÀÕgÁÃë7Øsò˜|£þ m¾ˆŽ•$Q,/¤P»BiÉí»ó2R_dzÈÓi¬¶]?L›²¢É·ï&ש‘§õ… ƒ6¿@1ïè¾!H´2Öª¸€¬Ñ•LTvpÐûê‰Âè­«‰ûÕ­9”…ÙÛ öHÁø ¶3ä=Ò_¬LjéúîT_¾™¾êD:Þ "Ö>j×ãc:=ó[ßÈ#
-õ"ñ^"À„e!¿ãªÂC{z¹"¹ØR.R³w e,¼™Zòœ‚û×Él#Ëç7· ¥*åBÁrÊJAÀlÛª2uãz¹–øŒƒN&‰ŒºÎŸÀÁCùf‘S1>‚«iÔU’µdG¤3µmká •SÚÛ»Íb¤ãùñµ OUP©^ÑÍ°ï6ØÂÎIjx0Oð5êD…ÜÉbšº”«m~¦V©M»Í»Ã=°
-î#Wy7Ó™0QºWÎj)“ÙV}$÷ši Ú܇ £ÔLÈoÐHô èp(Ïkìÿ?”ç³…[)Ž»åµÊëÓ×ÙåÝPþÚÍd¬K Ï)>̘S¬cÞ–vJîéú}ú¬În—ê—©”÷!$ÈvÂ…S¥SÅMí?2¨Å^a,íO˜` ÄÚ„Á’Ê‹v$§$6¯~½s;ßO,“5È!øÐœgà3EoÃøT‰gkê dk¶òX®hˆdŠ6x»7Û¼Ò[TšÓTçKVkÛNBlÅ)Å
-endobj
-827 0 obj
-1527
-endobj
-828 0 obj<</Type/Page/Parent 794 0 R/Contents 829 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-829 0 obj<</Length 830 0 R/Filter/FlateDecode>>stream
-xWÛnÛF}÷W ô°I¾ðƒ“Ø…Úum¥AQÁŠ\JLÈ]f—”¬¿ï™YR¢è jÆDr.;sΙá÷ƒ1ð;¦ó ŸQ\¼Ÿ¼»=¡ñ˜¦)îœ]œÓ4¡Q4hïRÚØšº"EƒÌ¬Tž%dtµ¶îUèYGƒ¹J¨TÞãrBÚ9ëT-µáäñ¥Ù‹ö¤Ê2ßò|}C |¥0Ç—·Ó¯#:G$0øbç™6ýWÚ#¹]éˆî "¹*‹ë\¹C*Ô7D¨æD‘ÉÒú
-qòÜ®”gFSæ)¶Î鸢ÙÐk-9ŠÝ,´Ÿ½mBO΢}{{H‰%c+BD—[û 6ª¢TÁ‡|Z·gã:øJU™5äô÷‰ÊáÒ„äë••(Ã\‘×>)«håyïتªtQ"†mí©ö™Yˆ½”VÕ’ÖË,^Jgr»X脬‰àsf»ö¨K¼Äé#ú ý3Ïà .V/¤”N΄Š¨8¶5j®_2>rŸÏÝÌ%1Ð/\é.#”Ù êUµ¤/uœ¥RŠmQÖ—ÃK¹Ñ$­øÀm-^>+24›‹V:;Ws`¨ÐÊp¥ÑÆ·½ñÒ; Q!OiZeŠª¸”&d±ö}Xêݵ¸¤¤{¾\mŒkèjçå”xÐ[RI‚oº e‚õ^lc$`
-d|­¡wsÍ€òþO(³Z¨Ì0”z9ÂÌW˜ÁâìKù8-ë ÉØo¦‹’=ä-Õ
-›ªÔa|D÷Ý}é¯ûïn[mí,9¥Ó)v%èPSË+Úh¿¦!ŸS›Ý”–‰ÓV Ç^jÈ.Ò„¤¹ª.»àžL.ÿs|Œ/O0>ÆãÜãýt} ·ù0Ò0? Ç¨J\4A¸TrÝ¢Ñ|©<ÖCïË«ƒL€›ÛXõ—¤-¤°ÎAÀžkëÄn³èôdövטP² ×ÄÖ¬´˜Å€9/jpÕ!V/á8"ûaXµ™ú%t‚ÛÙq:Ër+kƒ°3£e òŠ)¸çÄyfµ«M/l»…€±S‰ðð4»á¶èÛíRPÌÔ1 žØmd·™P¬J5Ïò¬9 @ÊÅÚÙ ë•ÎYïkÇÏ6 û·(q¬° hl£è=³
-wyå ÷ÛW!]?|ìÛìv…¦ÖW½„Õúò0ýröÛ¾WD€³L¼vò ×FÚþºž®o§7O²Œ¢(`9ƒ§.Këúbʲö#³¡P™ñÏb à¸@ç×Ìšó 0íG£æ¢Y»Ægç¿šáÍ«ó
-ö|}ÿþšýÊo0m\Ø8僫£`6|µüœŸDرô…ÌÈ惯Ä{êendstream
-endobj
-830 0 obj
-1609
-endobj
-831 0 obj<</Type/Page/Parent 794 0 R/Contents 832 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 27 0 R>>endobj
-832 0 obj<</Length 833 0 R/Filter/FlateDecode>>stream
-x…RÛ²“0}ç+–ouƦR ¾hÏxyrFOùÈ) ÁŽïN@­·qÂNöe­Öç(ALO‚œcŸAöÑCíÞ‘¤(kÊdÄ,Žc”rÃYÊpvºëЊ/zhଙ«NM¯ž—OÔš"I–Ö-Ï©uSÚ¯p­B/tçë;=9‹Aݦ†zÇ~7O*T)*µJt˜ C;j5˜]×!;ZCP=CIM]k©©t}%¾Ï÷,Þ–‘'X#ñÑãûèx`$'å¬@$/è»ì:œ½jŸÜÓá½ÚÀUŠ•±’­º@8xŒß
-endobj
-833 0 obj
-445
-endobj
-834 0 obj<</Type/Page/Parent 794 0 R/Contents 835 0 R/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>>>>>>endobj
-835 0 obj<</Length 836 0 R/Filter/FlateDecode>>stream
-x¥V]sê6}çWì#™)66&¼Ñ´™Þ™&sÛKç¾äEØÔØ’k ÿ¾gå0é¶sÃLléh÷œÝ³úkÑŸˆÒ˜fsÊÊÑëÑÏëÑ4X,èò¯Þá–¥ó`AÉ"Å÷8Æ×ZÒ–wà%`úX>=P<¥õèótAëÜ¿Ç“lü¸•“5Íú¤ÜÕÂ)½£ç/ôUéܼ[ÒÒ½›úÍÒ»rû»õŸ£)Mâ ã/¢Ü~ÂDxÄLfQóÛY´ÚI·kŠ¢vMœòŠµ!•KíÔöLn/éMži{ЙSF‹‚J™í…V¶´d¶ÿÇIÎÔbSH˪0瘼¥QE³&*aI
-^Öa<«iS˜Ý9舘žŠ¯ôÉ“(•–K~ 'qûþE”ØÖÎŽ”FÕšý¡Õ)üUéÉ֟ÃOŸ Um´Oƒ&à båcÊ¿ñ³Ïçù¬Ì½X8äJÇNHÎm€DýżӦ†ú¼¸“ÌéœöxÒ¦É:ϽƒG,6kÑï=x/ÄðPÔÛm*W±Z™jåÎd*¦kp2eFoÕŽ¹kp·ÐÍJYÒZÛ1Hd™|<ð±BÉcuW0$ìr¸õ¾Ùš¤=Wœ¹Î'¢0ZâôúˆjΛ¢"¼Z¢=‘ôz­š¼¬Ñx§0A÷)ç¦P®”å¦Çlõß|Ìx¢@k$qDHq­úÕ ?5ÀÈÚÕ¦(zð>à¬÷–3¥-“tƒ
-ùÀ#
-©wý½¥¿ â8Mw®8/l©P‹Ø *1A·æPÓë8y½ÃœËT‰ÌIØU·%ìØœ¡Z)^Dz’µ2ùë/fò5ƵDmþÝ•€“¹ô
-endobj
-836 0 obj
-1212
-endobj
-837 0 obj<</Type/Page/Parent 794 0 R/Contents 838 0 R/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>>>>>>endobj
-838 0 obj<</Length 839 0 R/Filter/FlateDecode>>stream
-xWÉrÛ8½û+ºr¥Ê¢Û’’99[Uª&Ž'Qj.¾@$("&
-Ûà
-Ï.C\}†Èä£ÌV! 'µ“D¹5òÜÒ£Zì%g–ÒºƒL½z’ÉÈî'†×
-ÚàH Ò§…BÁ
-p}apá
-@i¬‚p­’¾0ð¡bg}{wO“o̽w‹½µ'?¼dÄQ™¶•œÅ
-9çC¸3=Jèî¬/  Åœ³gUÈ.óñ`à\AE=H/6]žþd{
-µuÔºuË"Çh ˜òüõù;tŠX·té#`Š¥£‘í6GAB!@4ƒWAYÙèÏ°–¨éAzÇ4Þb'›Åïk‚ë€y™›ZgßÀ¤Eð›Vϳ¿”®Ÿ©)I(¼.a!ϸãùuUWQÙ¸PÕ(rŽ' ¤ƒwžãßQ{P}Œm“ÿ.¬9¨º …4àØS À£fô¸ûÿÞt«† ¡»sÐ|!ËCÐPÎ6w ä½®äÀ®qÖn¡ìO]q‘ÏŠ³D-ŽÕ m1ŽÅÕž18;!áï“P¥Ø5âF­9]mn0M5ƒ†+ð=ÌU³¯hÁSÔÕ 2ý…Á¯†‹fÙ$!Ø}JX^#OúYlºäYlÒgÇ˲Œ-,„=p¹T;+ î5‚épÚ¶+&`XÝŠ§áÑ€YÕaÖ"ÁÍ·4zïGÓFƧkŒi0›<,Wëæfë&ßë&·ÖØÃÄA`‘Ó‹ì7
-,Ž\d‘ ò1h1¯gÑ´£æïú9{vP
-!²–ô.f”_¥ÅÄÜÛ ¹Â=F%Ä<JVŸúN§jÞ
-íbY£.Íc’ø?14]^Ý€–ÿMÐå|físŠ^ýš¢œÞAÛî4"A;A,jé}(ãfD«$‚cÉðÏI†¾çÑk\àfxPyŽiRf } c˸{¦V&æ”0Y ¦\b›¡‘ö¾Œ«Šm£—¥2CgnûÓéÊ` ¸è¼­S~0€v‡úc±ÅJ°@ŠnâØHÍO´F¢ËÒY{à¸ÂÚeU]z…~qo³9åWñ) IÕ´ƒ–µí‚ÕWW;Î&t_JYÝÊœ§¾PÄC úãÒ…q¥Ã7|Ëk‹£ñð#Ñ8JZìõuÿHy¦|›F)«uÂϧ,=µ¾Þ~zsËcÊw@ˆrIk.BÛâð¦q×4n›4Z9&¯¼†-®ùüúûâ_ôìÈpendstream
-endobj
-839 0 obj
+651 0 obj<</Type/Page/Parent 635 0 R/Contents 652 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+652 0 obj<</Length 653 0 R/Filter/FlateDecode>>stream
+xWÙnã8|ÏW4ò²`+¶ã\ƒ=à\‰'3öÂX /´DÙœP¤G¤âøï·š”r(³‚ŠE²««««é{êãg@§C::¡´Ø»˜ïÞœÓ`DóoNÎðQ?é÷û4O;ƒdÐOh±ž&9Í×ʬ]Y󋧅-ÿ8˜Çþ qoxŠý¬5ÖójÚb™#a2ÚÙŠœ¥'o‰_>Òþvmi[Z/‰?q´QZ’Íɗ­÷ñ™44!W­VÒùpBfqˆÜÐÄJ(CœÍ0úÔ%CÞ<WZ‡M©Ðevk’zåð$áD;sÀÀ
+µZ{*¥È8(åŒãj2þ<ý2›ÌÿìC
+üŠnÆ_fƒ·‰R‡q¾J#`_îÂ!…Pš)Ð
+ØmÙiäÖ­J[m‚¶ö‘ Ÿÿíz|uwM¹-)“G¸‡ƒ„f¢X
+Z GK È $M¥sy¥õ;Á«Ö2#ÔɯmåÀ‰còÒµ£":ÛªLvÉY*Än‰¤œ-¤5’¤v2„Y«ÀwI›Ò.µ,Bþß>É2ÅjR>¡¿ÀAj+ Ó*ìæ$‹E+*#á»TZ
+p¥œ«d@É;'Ø˺]¥ES¥\=‡ãL÷·×ãÙ59 y'AÕ&H:Š ™e6­
+i¼ðʲ\À«³U™J
+Êg†Ѯ耶K6lº·Å= ÐWñfÂÙÇò%t¹¶Qà :ö6µšnå“ÔïųŽ“bŽ…³» ÖY\ÌS(¡eêN­Ê¬ *µ(\µÙØÒ;:î¬ïòË·ënø{ûç¬K·ãéÝx:h³?Æì@O烶Ñ;ƒ?¥œ‡¤-ÛB!žUQ¯Áp €ώɽ´
+™¤Öäïsî„©ÂÚ•/"GÁG=\+øÁ‡–<ü¸ÄLë“À?…ønKåw/ßÎdbÈêL–·v0¾à³qˆ°háúÑAr[Õ–f$ €eÌ”2™±V…ŠÊ”Y÷¶¥æ Á ÑÂ:®X˜V°m™A‘!=c·ØëÆâ£ÄŠpcŠ:ÛxaÞ›¦œŠ5z׊[J [à ²'´®XÁ»0ÿš"¯@Í,†1a—.­àÑèw¶÷E¾X¡ÄÒÉò æ˜NXÀ!áz*kÒ0°Q°F»]FòyNA}£AªŸ†¸„jc‚@Á£
+I[vÜ’Œ(ÃVùu#8˜Ã •«O¯–ÖnÄEíÕÓ9êTþ=?æ{Nps?›ÉxŸh:ꡃU€k*Á¤¡ÊŒ¦`ÆêËR;½).—ŸhþÚ³›RÁÚT²ââ³4TrS„ ÿªÉè¶ÑÖç—÷‡“{By¹ ›1Õ¿U©¨€ «„n€1 ›Š—G-y†O¥_ÊJµÏåkZbO¸WBf?nM+räv¸$ðκéXÙU!–è7µ¾¬VªÃ›³úv089Mønð³ñÝŘ-ü;<7þ7w(Ž×‹‹{§C|MÈþ×ׄÑY?9ÇW ,?æ#p›øº÷7¡‚ñ¡endstream
+endobj
+653 0 obj
+1513
+endobj
+654 0 obj<</Type/Page/Parent 635 0 R/Contents 655 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+655 0 obj<</Length 656 0 R/Filter/FlateDecode>>stream
+x•WßoÓH~ï_1êË©õ%iš–RZtèhË5©mì5Y°½fwÝÿþ¾™]‡`¸“N)µ½óã›ï›™ýz0¦þé|B§3ÊëƒËåÁõò`”hvñ4›Òôâ¿'øï4•üú÷Oi<¥e‰ƒ³³³lFË‚p`4¢e~4ÎÆ£lšÑkgš`šOT:[Ó›Û—S°¤èyetèõó'ËÏ05¥ñ8š:™œÃÐÑÒRç5>lÙ€vÖ*ñ¤•©ÔªÒôhÞûzu²R^D^»G|)žuùFkëmmGSUÔh|÷¹­[ a­ÙýˆNƧلÝÂZ#kýäTÑ{œÆ‡Íî´i|P°†‡äsgÚ@tˆƒéaF÷ZÁ ^ò‡®Ëƒ± ~s¤ò •ÖQmÝÐw¡Ró¥˜&3àÎP¬50çÔ+ÏÐ-Þ/Þ’[$Ü 6…Õžê._SŒLÕœ CŸ#Z$ÞûÏüÖ?fô2
+KaÛâ”-û¯“ݾæ+MÔjìk`±Ú27—‰3d*[àïÐéܺ¢·t8 I  Ú ŠB‰0àljN5Ÿ4G²Ú„„Ò+²-T‚t‰/MÁΘ)‡…n¶àD¡ý!€éœ•ounJ£‹ŸüÖkÄØö›û2@šµ‚sYÐÈŽB/[¢Â”%8=Šv~Ì>xgšùfôV;F{B†ƒÀª^)Zi€¬Ñ+&´V(ŽC
+,;4gÛ¨`ðœÊ¼ ÕÃÑÓ¨UÐ2èZØÊ_›º­tÍAAŠ¨¥¯ÊÀ÷J‡.ßs‰ÑÄê îåùæ
+:¶,èPvUµ… *:g Qœ)$#1¼Änôõ*UþcÕ(ÁÔ“.…'€ÄáEbIײ×É‡Ó ¡+L>̦ÇTh´`å¢q0`‰at·xž¥Ñ%‰àrò]ÛZüž#^<±«qF à+Tg0Zë½a©!’A•|É:‰¼vúk§ý0mµ²(e4
+ ¡îÌ\éŒ_»zäÚÃïà ¨ *^ò79¤ “èeÇßs¡ÏZ:z¥ƒFÜà©àÇÌ?á|µeD,ŠTC,I ÐdͦÚH¹¤®{EH0€þkÕ¢N°¥’çæºÜEýN•cŠ™¬‘Π!sð‚$AOÍÀ{² ò샜ö…]'u€‘žÄ@Ð3åÑÌ$-€¾QÛŸ„þò
+‚—iФ¡².xU
+üÿ‚?­&¼qe3)Œ—½ AFìðĺ•Ä‰À^ûWÏб2IoFu1!Е…«ȱFݘ jØx
+ÛüúN·KDŽ/dì#ч#Ï+3¡ÀꞀIMbŽ½1£”:ˆzuè\ƒŽ‚a¼·N 0f-ˆô ä¯v4“n!ÐâH9Ýý9Tä²Hó?¯¨¾·´à
+=4êQ¢*¨Ö˜Ù[h&¶‡…£WÖØ
+endobj
+656 0 obj
+1764
+endobj
+657 0 obj<</Type/Page/Parent 635 0 R/Contents 658 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+658 0 obj<</Length 659 0 R/Filter/FlateDecode>>stream
+x“_OÛ0Åßû)ŽúT¤ÕKš6i‰4¦fo¼熘&vf»|û]'tƒJC(Še+÷ïïœüš¤HøIQ,åPÝ䢜|¾Ú ]¢¬ùK¾æM…D$I‚RÍR‘&"¸‘}¯Í~zrFväÏÊGN\"MÇÄù¢àÄÙug»G#„J×592ûc¬Ah·—ÒT{£ŸÀrñÌrGh­ÝA†!fz,NöÓØ<Á<ÍÄ"6µ}ÐÖ`K4Dûî^(kj6è塶©[/bö×rÂ3"Ï2^—ë‚׿Ž#O‘¬6›¡Í ”Bà;ßÖᲑNªÀ»-…pé½o©óŒ%"­uKRüÖ¡TŠ‘³QÇÂzÀÖánÖjf~#ÇÓ}ÂV ¬;²U XyÐÌà_-üÝÙúšV¶ëˆ¥ˆ²½!~­®†D?FÆñ"áFeëí ×I÷·ê ¥â8,‡ÚEEÆ‘@O²ë[òì¾K°îùµ>«lõ}Ö/ÎKóBD;³[_Ùv{~sqŽ[g¹&¾XµçƒŒ6‰Yó1í}“/׉ØðŸÁ>+^œócòp›ûendstream
+endobj
+659 0 obj
+452
+endobj
+660 0 obj<</Type/Page/Parent 635 0 R/Contents 661 0 R/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>>>>>>endobj
+661 0 obj<</Length 662 0 R/Filter/FlateDecode>>stream
+x¥V]sê6}çWì#™)66ÞhÚLïL“¹í¥s_ò"ljlɵdÿ¾gå0é¶sÃLléh÷œÝ³úkÑŸˆ1Í攣7£Ÿ7£i°\Òå_µÇ,[̃%%˾Ç1¾V’v¼/ÓÿÃòðéâ)mv@Ÿ/–´Éü{<IÇQ:YQÐ'íä¾Né==¡¯JgæÝ’–îÝTo–Þ•;ÜmþMi'
+8]|ßX,µQŒ‘‡OÔþÎM*ræ“úoÿÖ4ËÄþÊÚ£<`>Í—˜Q ÎVí·æ
+ùÀ#r©÷ý½¥¿ â8Mw.9/l)Q‹Ø *1Aw¦®èuœ¼ÞaÎ¥ª@æ¤köãE¥Àm ;¶g¨–AŠ×1‚,e¥Lözç‹™|q­Q›w%àd.=
+endobj
+662 0 obj
+1213
+endobj
+663 0 obj<</Type/Page/Parent 635 0 R/Contents 664 0 R/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>>>>>>endobj
+664 0 obj<</Length 665 0 R/Filter/FlateDecode>>stream
+xWÉrÛ8½û+ºr¥Ê¢Û’œ99[Uª&‰'Qj.¾@$("&
+ñ$Ihúx÷†D–Yé\BwΙT /3:*_‰ásò…„+•8ÑN’Ñø±/·ß/æ4]\%KŸT >Ü·'Jœ¹ ›”£OŸ ‘”Â+£]¡8Ä¥ÔìE¿WÙ¹ÙKeI®N Ω½®¤öndXÀ®°;åb6–2åR+ÙßPš´ðµ•ÑsTä`'œJ©”O² 6ºd¥¦ªj­Òè+yñ(JN^í”ÞŒrˆ‡ }U+ùnŸˆ˜uäm_š: ü¨%¢CÀ{©¥ w­¬„ÒŽrõ r„‚§‘Áƒ°^¥u)lƒ+<» qõ"“2[…0œÔNåÖTÈsKJh±—œY:Hë2õêI&#»^_
+f „sH¬€q“‚øt`yC=ð2V€ÐGZ>-B°Í›Ô”¤ªC’ˆBÈ,86¦fð•ýzÑ¢E%_°/
+¦!¸É×›Mù„HàÊyU 4'4hÂ
+ i¬‚p­’¾0ð‘b¾9úööž&ߘzo…{+*jO~xÉ€£09j+¡
+8‹)
+íbY£.Íc’ø?14]^Ý€–ÿMÐå|FísŠ^ýš¢œÞAÛæ4"A;A,jéú|(ãfB«$‚cÉðÏI~¾çÉk\àfxOyŽaRf }S˸{¦V&Æ”0X ¦™[b›¡‘ö¾Œ«Šm£—¥2CgnûÓéÊ` ¸è¼­S~/€v‡úc±¿e%X E7qj¤æ+Ú ÑåNé¬= ïo\aí²ª.½B?Œ¸·Ùœò«ø’„¤jÚAËÚvÁê««fº/¥À¨neÎC_(âýqé¸Òá®òÚâh¼ûH4ŽÒ…†Ö0k}Ý¿Qž)ߦQŠÅjðë)‹EO­¯w_ßñ˜ò¢\Òš‡‹Ð¶8¼iÜ5Û&VŽ‰À+¯7óä6*Ñ-_í¿/þ0WÈendstream
+endobj
+665 0 obj
1684
endobj
-840 0 obj<</Type/Page/Parent 794 0 R/Contents 841 0 R/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>>>>>>endobj
-841 0 obj<</Length 842 0 R/Filter/FlateDecode>>stream
+666 0 obj<</Type/Page/Parent 635 0 R/Contents 667 0 R/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>>>>>>endobj
+667 0 obj<</Length 668 0 R/Filter/FlateDecode>>stream
xWÛnã6}ÏW ܇zÑD¶¼Þ8»oIÛè^ŠèK€‚’h‹‰TIÊŽÿ¾gHÉV”¸ÛHli8sævføÏEJsü¦´ZÐÛkÊë‹»õÅïë‹yrsC§?v‹/sZ¦i² åÍ
Ÿé
-Ÿ­¤ Á[è9þüìã{J—´Þ@ýõ >áýœÖùôm²H– ½Y¿˜}L;±éLú|¦Û+Ÿ—Inô&
-,)M£ž«Å
-z¦ëR9Ú¨J„¼5•#_J¹oEEZÔ¸œ©Z¯Œ&/ìVz—Ð2ñ˜?4*Uu R¸(»“–Lö]æž\#sµ
-Øl~cªÊì݇ˆnNï\JW‹w »9¥îç'zÝ#V…Ð>íMŒŸÓöæ^ÚÊñ?„†½Þ¨mkÀàQrî|÷|‘&×C{@˜‹=Rh¬áÏ)¡ÛÊK«an'I"âJ"þÆRPclA¢E´ïbFÂÊ×<‡Ž¶£åà„#¼V…hh¯t¦tq+EaöÿýÖš¶9É>wu—Ò8ïÂ\dV¡eð"GçÂÃÚ^”ãÆæ¹ýh–C`œ_¨D]«‚Š¬óã®sè´ô{cNqˆzÏT‡D2íñëáÌ™|4Öx“£ »Èmœ‘·M>ˆñõ»Xþ½úçxf{~¸â¼Ž=úuƒ
-Ê$iãe-·E#Ôå*
-úCéö‰\Û4Æú@òÉKÍ¢¸¡ï@Õ]T)ò>)½±ÂyÛ‚ÍÙ1‚4rª
-ÚóJÁir€D†™
-˜›¾H÷éë}èÍ€á¤Û¢@18É“ÂЖx š‘åM«sž ¥q -eÔ
-q‹$ö%È
-éß'_éQ88çLÆa$…&Ø—
-ä”T
-¿t¡£z5[~:(ÜþU&ÙphÈ°¬Åuì¦_ÍЈýb6\ÃÒkØÛ$.ƒu δù‰ wô„x=¯Lù¸— €žd‰óaeÁÔµ"3m$ÛÐüœ{¯Xt‹CsíâsÀÿGmöšvÂ*Óº„û0å@ÃÀ,ÊcÀÉo8)!zîÈ6Ô ’6¹¤IoŽÕó÷ÖÁ£L™ˆ
+Ÿ­¤ Á[è9þüìã{J—´Þ@ýõ >áýœÖùt‘,’eBoÖß/fÓNl:“>ŸiçöÊçe’½‰KJÓ¨çj±‚žéºTŽ6ª’!oMåÈ—’Dî[Q‘µ.gªÖ+£É »•Þ%´†L<æÊEU¨.Êî¤%“}—¹'×È\m ÀÇ Ç0æt•¾…Ã0¿1UeöîCD7§÷ .¥«Å»„ÝœR÷ó½î«BhŸ‰ö&ÆÏé {s/íNåøBÃ^oÔ¶µ`ð(9w¾{¾H“롽F ÌŇ)4Öðç”Ðmå¥Õ0·“$q%c)¨1¶ Ñ"Úw1#aeˆÎkžÆCGÛÑrp‘F^«B4´W:Sº8È•¢0ûÿ‰~kMÛœdŸ»:ŽKiœwa.²«ÐÇ2x‘£sáam/Êñ?cóÜ~´Ë!0Î/T¢®UAEÖùq ×9tZú½±G§8ÄG½gªC"™öx‚‚õpæL>k¼Éц]äŽ6ÎÈÛ&ÄøÇú],ÿ^ýs<³=?\q^ÇýºA€Zëä%I‘—d6LNR-óR
+´Mî ´1òàË„qLFXa1¾0;PD§¡<¸ôc &‘ò&À§LÔ ž0ü`3˜Æ!H·ÜÆ ¸Æ(íIyNê1Ç°1Ω®VŽÐ‡a}Ô  †“ äçS½ cñî%×feø42ÊÒ¿N¾Ò£ppΙŒÃH
+M°/È)3¨~éBGõj8¶ütP¸ý«L²áÐaY‹ëØM¿š¡ûÅl¸†¥/Ö°·I\0ëœiò=ïè ñz^˜òq/
+99îvL­­/#ÚôÚ—#WÂ\(R,l…0Jñ Ô)âä@E Ì,nYÌî¨ZNzŒ*ÏõÓ&w²"¼À[w+tŒàÈøÐNƒØr‘¡ áìqôÑ8–,Bd% p€ûq
+ò6Ò<ÜC"Ì‘eø†Ed§˜'ÁA!»qØÍBìx¯‘‘x- l³Ýçˆ3ó="ØÀâ%¢¿ÌÜt¬Ÿ^¯’׶4^Sîo?ßÝÒ7kÂýè7“‡9bÇȯ¢øÕjÛ]Ñßî^¿ü,WKè r霃¿þ¼ø&wÂendstream
endobj
-842 0 obj
+668 0 obj
1574
endobj
-843 0 obj<</Type/Page/Parent 794 0 R/Contents 844 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-844 0 obj<</Length 845 0 R/Filter/FlateDecode>>stream
-x¥X]S7}çWÜÉéÔÆ6ÔNÚ Nê)ŠÍ¤¼È»²­°+m$-†ßs¥ÕÚlfšfš0lé~œ{î¹wùz0¤þétDÇcÊʃ‹ÅÁdq0èŸÑîÅ®ñË€~9=ÃëÉÙ)^‡#~ÇJZñü ;í Î}Ð;Z¬`{ [‹<|< EvHÍ¿{­¾Ö’®¥¿˜ÞÌéZ”Òýúvñå`@½!œãR{6Ý™_þ1½ž\ŸÏ&ïƒßé7šKû$mø¦2IÊ‘­µVzMFÓÞñ1|̆?I-­Êh&²ÒˆñÑÃa
-Wãׇ·?`u½z&tŠÚ!øÿõç›»??ÝÝÜß¾.9æ¦
-i çÉ…5[xhb ûã}H?YSWÿ õ›Á+h$V®»“9-_H•²\JëȬ¨½ù Úsï‡Ù^"—F{kŠ‚­1S
-³FYcÍÝ·™³Í+“‰¢ƒÍØlcª‘©–>²áN:S€}ÁÊÑÇ™ò½!õFãþˆÑžzrS
-e¥\"y¼.Óáì‘ôÙÑÆ8ßÂظǕæȇë9å‹¥p>‘yLˆ¼ çL¦ƒ²U~C@Byn¥sýÄÜqÿ„±¼çUm‚¥Ê(í™aY!¬Z©,¤ÕÅúç&›a=ŠÕ9|õ®l‡´R‚Ò\"I¹•™±¹£Üpí¨²æI岃5N¥ääÈ¿T ÑÊØ2F{H|6§ÏJçèI­¤ö°++ w 4êT€Ÿ·a.X@rIø~Çk)^(pJÊ\æ}:×$ŸEY!\ô ;âQÁM(¹FzßB´Î.”YJ:NcûqTÒö Ü^!¡è,…šàcÆ5uä€DÈ%PP4@‚½žEÔf°X´`0¦‡Ã'%HtH8/­y‚?¼%\%©ëR‚«`rðÆ*”º*€¿O’Ú ]ˆ~l«õë@„wLÇ©•˜Sè%tŠ£‘ ¨¬]÷øŠO‘O ék¨Džš E‡w
-ôG¸c¹t}ú¼Q`>IÀÚñÝd -.ZY9M`Ž# Ádð˜:»a°|ÓB œY¿Ùû¸æð†€ß›Xî7ð” M X‘UíØ4^0]á
-Êê_s7~­•å<ÀX]Î&6ë•€XxÞòÖ”`ìΞ=ñÞ&0.*l?i8¶¥J­Û <&
-hÆP²åKÇõ5 ‚ó3#ª†b£¿ì1ºl–¸„‰£.(ßäë÷bÁºÏ@-â–Ä?òsXÈ0ºû—&h›i¡2üz†–[ì%©0dP#SÔa(—’AQ®Ä´£y&[\„HF}VEKÆ»v³6
-tjÙÍ™8ìÛș˙|Fá.žÞvÊØlXI^$(n±ÎSÒÞ ²á%IÒ|DÉÊZóhN‡Ê³cOÃAoø a+«=ï(ÓîŠh‘º|…õ›÷YžQfé±6rš» ‡bp) ZYS†yã-Àu Éñš8„ ­ ÞÀv²ÞÍDPÄy3Qkl ù¿Q­¹ÔöpÊ{hÂ
-endobj
-845 0 obj
-1992
-endobj
-846 0 obj<</Type/Page/Parent 794 0 R/Contents 847 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-847 0 obj<</Length 848 0 R/Filter/FlateDecode>>stream
-x•WmOã8þί•/ ÑÒ–7­Nâ¥ÜU‚.G³·Z©ÒÉM\ê%±³±Sèýú{ÆNÚÒSà¤RÛ3óÌóÌŒîô¨‹ßöéè„âlç*ÚD;ÝÎÙ­?Š'üÓ¥~Çg§üùé¼Ó§BÒŒwà%ŽY}`ùáí1õzÍpúÉÙ)E‰ߥ(Þ:¡YZÚ¹ÄßÂdäæ’bÏåÕDB“pNf¹#gH¾Æs¡Ÿ$ ʤµß^”›c­p”aŸÒü$Mi*É–Ó2v„ûÑ.µ{Gð4JöœÊdÛ”Ž™Š¥íêÈÎ %-2IÊ’Ò›¾X‹þU!­IK§ |Ky.ó`Ï–q,er@SËQÔÞÄBoY×Æ.›t(šÃְÀ ´®Né'š™‚J+ Km¦rì–
-k žˆÊ“Lä9sÑ
-©”É6»† ú2WÌ FÑ<[JÕ³¼¨9ç¤õ¨ÝÿØHÕÏ.]›|Y¨§¹£É^<Ù§ÞùùÝ«¸0ÖÌ^ym ¬8ãÔ­6×
-H$=K”WÈe…B-Ta •Z6&ÁníÙÆay*â &dv:ø›–™T\rViht<6EU ™}›Á¢×ü¬•Â+*4Ï\GkeŽÊ‚Ð7R)à¢Aç°9\gÅ;1 –Z»­uÅm<œ{’Z^žgHS"Q襧ˆRøJˆòm²,pÍÊð= ð£ú6'r*Ûd¿1Ž½)wŒÊüÂðMs-‚»ËÝ vZP¿óZ1œÒln¬kv‹iÊ•™Í¸Sù„ûsÞä«“Úr`¾ pÿÝ–l£ã^컃VÜ|¹¿øœ˜ …ô·–G×w_oô™Ýf9|´ájðûpô÷å]4x]Fy2Ýüßµ“I÷Uk”mt;/”ö ÕØ1¸ä¹)Üd¿)¢¦çt»_èe%ój’ñ5¦–0cÕS„¥ÃÜ
-SL,ÀÞÆÓ9½¡t€Þ(y^ŠÄ‹Oøµï"~`èÐÕ˜‰2u~›b²ÍÇó\´:2 RXN+Wn£ÑcÄ 2§d 3˜}¼±l&Tj]$› Uñ­pjín2¬…ÂðÖšX¡Šp؈´V§¢¢ÌÈXÍT(@5{¹Þpï‚’bÌ¡sóòîÉÓ³°à˜š'oü·P10žÊ¹X`ÀѵŽ¥^¨Âh®;<)˜åF·9“,ý€ð*Ô$Ô †$àt@a*Õv­@O DÊÓr’Ðj(ÜV=1ãx)Ûñ]Æw“ ?ç¦/ÌkG”HÚÕÓœ-úliôŸ‡
-endobj
-848 0 obj
+669 0 obj<</Type/Page/Parent 635 0 R/Contents 670 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+670 0 obj<</Length 671 0 R/Filter/FlateDecode>>stream
+x¥X]S7}çWÜÉéÔÆëP ´3@œÔS ›Ix‘we[aWÚHZ ÿ¾çJ«µ³™iši°¥ûqî¹çÞåËAF#üÏètLoN(¯.“ÅÁhxvF»»Æ/#úåô ¯Çg§xÍÆüŽ•´â+øvºœ?ú0¢·´XÁö l-Šðñˆù!µÿîµúÒHº–þbz3§kQI÷ëëÅçƒ 28Ç¥îlº3;¿ücz=¹>ŸMÞF¿Óo4—öIÚðMå’”#Ûh­ôšŒ¦½ã?bø þ(µ´*§™È7J#NÄG‡)\_^ÿ€Õq÷Jè™Ð)j‡àÿOÔŸnîþüxwsû.[rÌïM%ÒΓ k¶ðÐÆ8Ά'û~´¦©ÿê;7£¯  X¹VìN´|!Q–TÉj)­#³¢îæw€êνËò½D.öÖ”%[;b¦”f²Æš»ÿn³`›W&e›°!ÙÆT#S-}dÃt¦û‚•£Ç”eLùAFƒñÉpÌhO=¹iJ€#I”üFø€S¢Ræ¶PâˆT–ÌV1Ï G5*Š÷I,Í“Òbªó—¦'”;añ&ºÍ8¼MÞÐâòöhzK8é<Ê#¼2ÚÑvƒ’ŠßÀ/Á¼{A1+E¥4êj…7–¶
+e¥B"y¼.Óáì‘ôùÑÆ8ßÁغǕöÈûë9‹¥p>‘yLˆ¼ çL®ƒ²U~C@BEa¥sÃÄÜ“á1cyÏ«ÆKµQÚ3ÃòRXµRyH«õÏ!L6Ãz«søuÔ»²ÒJ•Js‰$qäVæÆŽ
+õ£Úš'UÈÖ|8•’“#ÿR3D+c«ì!ñÙœ>)] '´’Úî¬%ÜÒ¨S ~z܆¹`É%}àû=¯•x¡À)) Y é\“|U pÑ·ìˆoD 7¡äé}ÑVp8» Rf)é9íÇQI;$p{…„¢³j‚×Ö‘!—@a@Ñ öz P›ÁbÑ€Á<B˜Ÿ” Ñ á¼´F9þðšp•¤n* ®‚ÉÁ«Pêª
+tÝã+>En<¤o Ej‚Þ)ÑSáŽåÒ éÓFù$kÏw›€¶¸he æ´a€9Ž€T“ÁcêìJ„ÁòM -p"dýjkìãšGÀ+~¯b¹_ÁCP‚4`AFVcÓxÁt…´10Ù
+ŒœœZëЂ|Ĭz€!¡;a$°1¢óÆ* ‹ëeÌZîÊ}ŠBm9VV<
+4ΣæÉ‘1ÿãünB³¼$“¯CDuóM; ¢þ~•r‹PâœÇ9ÇÛY+óÛaŠðˆÞK­ƒ Ž § J/dêÐ3:ÚtñðFâALmm\„ éÆ–½ŸOîÂûIè”÷Ø~Iö
+Êêßp7~i”å<ÀX]Î&6ë•€XxÞòÖ”`ìÏž=ñÞ&0.jl?i8v¥J­Û<&
+hÆP²åKÏõ5 ‚ó#ª†b«¿ì1ºl—¸„‰£>(ßäï÷bÁºÏ@-â–Ä?òsXÈ0ºû—&èši¡rüz†–[ì%©0dP#S6a(W’AQ®Â´£y&[\„HF}VeKλv»¶
+endobj
+671 0 obj
+1999
+endobj
+672 0 obj<</Type/Page/Parent 635 0 R/Contents 673 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+673 0 obj<</Length 674 0 R/Filter/FlateDecode>>stream
+x•WïOã8ýÎ_1*Ž•hi»,¿´:©”rW ºÍÞj¥J'7q[‰ ÷×ß;i §À-H¥$¶gæÍ{3ã{=êâ·G§}úxBq¶wí¢½nç쌶Åÿt©ßÇÇñÙ)~:ïô©´àx‰c6X~t}L½E œ~rvJQâßw)Š„Nh‘–v%ñ·0¹•¤XÄ+yÈ_5‘Ð$œ“YîÈ’ÏñJè¥$A™´VàÛ“r+¬Ž2ìSšŸ¤)Í%Ùrþ·Œaã‡èï½.µ{ái”8•É¶)%2kÛ!%/hì~±¤E&IYRz×k`п*¤5ié”k©1eÌÙ2Ž¥LiŽS9ˆÚ™XèWƵq@ËæF'ŠV0†5ì/(­+„SzI SPiea©íÏTŽÝ„ø ;Y(ëTLfá­å…q&6i§²Õ?és <¹Ò7¥ód Ž§Ê­\"Mù™|™Ò0ŠªÓ&Ò]Ž¿L)„ìÓÁÆcì@žZzÅÞKšŠl.^…(”êQ¤R»p$6¿8 ›ìZÞ_O2p£×Ev§˜]5£Ž®Ï©‡h˜?ŸNC`[õ;Èiðäæö÷/ÓhJ •Jvh—xí>xÀ~ÏDDkä1!ç;XM":†Hõ»à´òy<º†D*2oè4¼˜Í¾'“h6›~ŸF£ÛýÙìê~üçè~:›¢áKo@ê„b£PÈ0]Æw4HÐ9ÆË]Jj0ÊAÉ+¨s¡
+˜3¬ÔþP…Çkã>ü\`Xf©Îµ·Âƒ'¢ò$yÎ\4…B*eòš]cP}+æ£h,¥êA^ÔŽœsÒzÔî
+l¤êgŸ†&_j¹r4;ˆg¨w~~F·*.Œ5 ‡×E^+Î8u›Í5
+Ë båÊm4zŒX@攬a³7¶3-„JíÏ‹d´*¾ N­ý]†µP–)a­‰ª‡ÝˆX@ksZ *ÊŒŒÕB…T³—ë ÷.()v–VæéÍ“çf7`Á%05Koü÷¨b`<—+ñˆG×:–úQFsÝáIÁÔ(7ºÍ™dé„7¡&¡n0$§C
+S©–°kz
+h Rž–“„6CákÕ3Ž—²ße|7©‘ðsnú„¹¼vH‰Ô¡]-WlÑÏ÷`K£ÿ<û@MO|…xÉK>ýQIt¡ŸgÊÔ'nÍÅ­µÿßzR‰sº[½¿næ+4ã˨YÒÄsÏó¸ 5<ø¶LÙV-Ÿr/
+ÆBલð È7¤ÅnÚÙ)}ŒÂ¶e ú:¶ç‚uÆ¢:Üè8gsc&·HÕ?ØTuŠ0Y#
+/=¿­yüOqéã‘°5)Ót
+Í¡»NÙ–õFL‘ HF'mu 屑 ]ŸU——ÞÉI§G'ç½Î ÏÖÓÁíå€î
+ãïËW&.¹Xø;!ïk÷NN±¼}ÚÇ¥=9xãÊu|zŒiݯêõy+îvìý Ì£Åîendstream
+endobj
+674 0 obj
1741
endobj
-849 0 obj<</Type/Page/Parent 794 0 R/Contents 850 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-850 0 obj<</Length 851 0 R/Filter/FlateDecode>>stream
+675 0 obj<</Type/Page/Parent 635 0 R/Contents 676 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+676 0 obj<</Length 677 0 R/Filter/FlateDecode>>stream
x•W]OÛH}çW\%›• $!å£o@Ân$HYânµ’¥jbÉ´öŒ;cù÷{îØqZïBiilïç¹çžü8Ò
;Í/œ?¾Ð lŸÂVûÇ
¢Õº´”$–©¤ÂÀ’ˆ©XIJ³•q…£Dá+£H:—”iºîS°RŽ¾Ë5á¿RÇÒþ|;ÐÑ‘ÂÃŽá0ÌD´RZ†¡[»Bfa•ÖJ]DFÖ¤Nx$í“‚ý0L…΄ækiÃ0Vd²O4\;„ Œv+a¥kõ©´ßÊGå
‹p*ËÓ5‰8¦N^.Su8SŸ$ŽPb_ZÙo³ÚvµÔ½šþ1›%3Ýé|òõò6˜>Ì/ƒ)WéÙØØ‘HSóLY™*GA»³ùõíçÉ´Õ®+Ê…B9Ž z´¦Ì%â4’cíÓ¥^“Súq¯?¤t”–±l5ü¬Ò”"Q:´±{³ì·XÆï¯ÀÒHn}HÚè£Ü*] &ŠÐ$qïàLs2[Ê8FhP&ò§-×­&Ê¢9páþ°MŽw.‹«Ù§i ƒ-ý( *Ũ8äçšJ. l5†ƒ­nõ¢O>—‘J€ZÉzi‰2׿NêýU
{bž|À$HÓ E«=BÈ$9Z#_
©=Ø?¶åÑvŸ†ƒQÿø¿g~Ä-&Ðl¦º÷SêN>Ý}Ô²
-
-Iþ(¿X­gú¬ÕËñ­Òå íW¸w,‹èØëæýnö~Íhp±üß žþ™qŸ&óÝú‘Ûw¾™Häb©RUx™¾Í—k¸­ظ(s&H±yP«jjäå%"òÖꄤæÉŠÑù×eÖ3•@Ûé¤C%¦˜¸ü•‚Ž )h-|Qäç•­(WõWpå5nÖôTKÀWžç&Fë×9ìm¾6ì7:š™¶çàh@™Ä÷ † 5Òri±" ŽÂ(ÈÒçÉk45GÂß}:^ªz×Ô])"ϨH—³tåò›Œ<† *æmòûÌWÕ·º9uŠþÜ«<#0®ôMðÖp¾w ‡5ŸðDÞÞUÜ‚ÞBËè;c½CÇYòîâ¼–ÎbS‚W.÷Wåàà[UúŽg£"P"ÐÊ‚^†ñ=³äv¯³]V<½õph³?ê‰5e¦Íë(—y—~?\´°ïyÍ{ÃÓ³>³Æ—Þo¿‹Ë»«Kº·Æweb¢’¹ÁcÓ?ªÞ:ª^ëý’­ÇgcÌ0›í Ïù%,„¿þ±£•Ôendstream
-endobj
-851 0 obj
-1653
-endobj
-852 0 obj<</Type/Page/Parent 794 0 R/Contents 853 0 R/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>>>>>>endobj
-853 0 obj<</Length 854 0 R/Filter/FlateDecode>>stream
-xWßOÛ:}ç¯ø´§N‚´)¥…I{€±iHpÕ^MWâÅM\â‘ØYìPúßßóÙNI3&]Ý¡Umì|?Ï9Ÿýë(¥ þRZLétNYutµ:ú¼:š$ççôúÑ<âÇ„ÎÒY2£ÙùߧÓäœIìÅÊbŽŸa%â_-,ÂÁþ†Æ_.(Ñj¿ós|Éýú„VÙè49MÎúqs»¤oÆ<µõûÕÏ£ñ—¥ixãdºÀ£Ë°çaôCéÜl-Ýh'-ÝŠJÒR6ϲyxO_T&IYr…$ù«UÏBjGfãP³ÉÒÉ$ãcJ¶–™Ú(™ÓíÕí’]Oè$=M¦ìòat+ÝÕÍÝòÐEB1v%²Î4Ò’·®‹%¡sº¹'‘çX°xà
-áH B|TqÃázG‚b2ÇY©8bR!äÕ§û1ÌYéÚš
-ai-¥¦GõŒOØ-¥°HOËP¡P öü'ÑútŽV"­•¡ÌèzlÐRTkAÎÀ&‡Ãmˆiqõ6¦,ÍVéGªEƒÔ9i)sÎ6¼’çHßywè°å;7²Õ:aGáq×ÐmT)?t{/¸É)LÏBpÿÁ©%ÛÖµi}¤¤=4sÂïÌCŸÞN¨µÿ1#ô …ðy!¥}.]ðÿ+Ú[ÃÁ2’@(.ùaV6éåå%éýÿs‚Ûˆ‰åvåí½ÉVßuø…!u è5ÙCÓB³ÅÅ+Õ{|î³w6;KæH¨ÏßYB_Í–Ö HÉHÙ´:sÊ }LƒK€G.ëÒì@±.Ñ,ð#©sþÝ‹ÅÚ[j½=ÐÃìPÙ(
-Àˆmkó,éû²£U"+”ù:Îq_UC§Uéa¤™|ðM¯/û IØ袋¢Ðé‹ÛÕM¦–à|¡=Fs8
-xyrEk¾
-ªöJÈØB€èÐÇ€Šø p_“ «ÜTòwJ`Ë äqç^Öùƒ0!Î(FƒAÊh„ÊÊ 5r;<óÆqzp) ±€ªpõÞt=pêû"…ɳ­AvÙ­¯@¨å @y؆ã™}âÍ~^BÂ6©:JCì1Ä>åKVýÈï‡ã<g£–lAD‰ƒãnèÚW+T/Ë™µã D^Õ%„¾GƲ8ß»ýYXâjE8&ôÙûLÓ“ôŒ01€õCà±²ô2µ+QRúÀ8LØÍW»à]8>f¢üþçåú,%¼0†¶¾úˆô-Ôc!Áí¶vªÂpGàià¾2Øa¥VXœÉLIÈÔ‚Kþ \éüa„±~àxyχ7q5dñ'6·°`;Çf÷Šj€¿,RþÖ²ŠÓºevZÂáG²†xªkU2ø=T›r0Hõ bŸ˜¦¸Å8\øÐßÝ:ƽ!ít€K½Ûß
-§‡PlŠ†:û‹ ®vAXÇ_ÎãI8/’”æó4Ü –—߯.é¾1<ÐèÚdmFù<9˜“°ýd1Åý3ÿÃýs¶˜á,ê7¤üÎÈý Â3ínendstream
-endobj
-854 0 obj
-1696
-endobj
-855 0 obj<</Type/Page/Parent 794 0 R/Contents 856 0 R/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>>>>/Annots 34 0 R>>endobj
-856 0 obj<</Length 857 0 R/Filter/FlateDecode>>stream
-x¥XÛnãÈ}÷WæI X´n–äò0Žg’ÆžM¬Å$À¼´È¦Ôk’­í&åQ¾>§ª›s7$@‡Í®êS眪֯Wsšáßœ6 Z®)-¯îwWvW³d»¥þÃðÇ ‹ð±Únð¹X$[ršr~Ï°K÷Õ7W4ŸÓ.Çæëí†v™<ŸÑ.<«r¯È7§“uµ'E¹Vuƒ½ê£ªI…}õ”[—êŒü¥J¶2^ÕÆVD6§½ÃsM…ñürê¬÷älScu¥ëWë^<5ÞTì§Øýr5£é|™,ÃäÓ¥­5µ›ðöï褜*u­™Š_"_î“ÔV9å¦Ð íŽÆSª¯=…䩶„µJky¡°©*¨Tž7 ºQhd¯
-ZµN®I ò–l•ð31ƒÝn—|Ô>ôßJÿæãÍWAè··Ð÷@èËä6¡ÇgújªŒ5íuÚ8S_Èž¨ü?Úר¦ÜØ¢Ä
-]郾NHT“jÀ”, >TÚLmzÑ[¾MTò’¨„žvŸÏóo?¨;³•¾æ¯i¡•£ZõkŽˆÉ‘7å©@ec2Q`£€ }
-ÆiU˜èl”éŠOz~¼'&LmSËDÄ
-?—¬MUiqÖiÈ¢ã ONìJ±p-´+½»…Ÿè)Dv6)ÛIúBóë¡ÃCà­s_&ß]ãÿÐ
-mã7ï/Á½bl¥ƒÉƒ–Ù[À[+Nè}QôA±r°¸ELÐcøð0ò.½ÊŽ
-£>
-t»Ø jÛqŽêŒÆò²FXæìéÄ4o½¶„þ¤HžXˆõâk&CGàÎgTš
-³-Ê×µÃØoB¾ ‰²XÄýT]ëò„~ÇBeù ‚Ê3‡Á‘çÖ*rä­›J~:»–WÂ!F¡øSÕ*À ëúÝÂЧ*="\jOhõÁX[Ç°Iò†'*›×ÌjgAæ­
-HìrÐ-Û
-òCH>ȳ­ÄÏ8ÖÍÇmœçëM2Ç&·a<~~ÿxÿž~rö˜6=Ø´) »üLÃòéf!ƒæÿ{å‡ÿ’µÚ0á$ÆbÆ ƒ-¹ú'¹äÜendstream
-endobj
-857 0 obj
-2022
-endobj
-858 0 obj<</Type/Page/Parent 794 0 R/Contents 859 0 R/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/F9 11 0 R>>>>>>endobj
-859 0 obj<</Length 860 0 R/Filter/FlateDecode>>stream
-x½W]OÛH}çW\å)TÅÄIH`%ÊR´<º"¨»šØãdÀö¸3cBþýž;c;ÄPiµÛVÔ‰gîǹçž{ùyÓcši2£¤8¸X|]Œ¢ÓSÚý0+|À±É$šÑôtŽçé4š’‘”á,>ãhܼñ‡üØÂK8è~ÀÐñÕ˜â˜üÎNç´Hýû-’am¥)E!)—/2?\<_M›ÓCª„Á;' )KF™o çJ*¥Leñùgˆl‘ÿм5ŸqÏÚ6)é’îo®ÿ"»µN–tæp»Ï’à©P¯2¥DàS²†»ÞlD´XÃe!EiÉ­…#U "’L›Æm<p+Ø–a_‚~¨2ÕKg¯”äJ–Žœ¦D—¥Lü£ ;Q,á"ÅEU®pR
-CN¾:µ[ã–J„Sºü ß’*-†Ã6¹^XÔÖÑRÂ÷ÎÖ
-ñªŠº ².–uFuUáÁCKÇhoÖ*Y7~gm5]çiˆeW!»ˆX‰u w£ô¸õ‚Ä9Ž¡ÉþöŽ‘ _9#RÅ9‹œ.¿ÞбøÄñ%f[¹‡áᇃQþ"“Ni£òäµuÎ¥ìEåSW¥•¥E/²ËYY ÊdF]q¹ÜG¼e‘[½3O¹.W€1×+ÐÆ©9¯|ÏõZØu HQÕ3x—¦¨'
-iã¸?𕯼¶q[©$4‚´é\’i„^ã7hï8nm$ÚR—™ZÕÆÇH•¶V-UŽBUï­õ ¨>püõ7¢“IÌÒåålŒ§V³Ž¯Î(†„°BMÏæ¾­w5‰N¢8¢{HÄ·»Ž7 ®©
-žé<×.u'‚H—éÄýS,#†…2•KŸàñÕˆÎ8®N‚Ró§åM-Îéoi[°!úZ{Úʤ6ÊméüM*H îk+Û6ó9 n¤»¸¾½{dAÔÙã÷Ëßû@qx³ ›]ÕÉm4mÄÖç®R–¿lË™ƒ1Èe¨ÔÐF¯³~ZxúwTBA³P‘+ˆ¾?Ñ-º‚õ¥M´‘kÐÈ
-£D• +…I]ýßè*Øä`{è¼^yÑËV ­Q£|­} ìè‰E—#”Ƽë¹D§ò£ÃÔ(,"~ÑNzùÛã?÷È0¨ð€ÁZ -š‘Âj̬0e¼6AÖR¾Óƒ¡C¯cAK½ª>’#™Sh¿íNó—* cdÁ2ßÜgíðz
-‚;ðâ~€pÉëç·ºîiºïœ>íCÔSZæHPIƒO ÛU]4ëé gl˜¾cýºÊŒ ‹„'\ˆ'³3˜S  ºG°†÷ˆ'°Î`àbàHÓ= kÊ{ËF¸{”»Yô»çúÍòxŽß
-x†Â*ãçMR5xð/Þ铆qöü–ÔïùÅKˆêOŠ6DL„@"ÛÌÚÓf'Žgó(¦ÙlîÝ—o_è»Ñ^ÿ.uâ!ö2Ÿ…ãGó1~õI‡ÿu­˜Î§˜ØÞÄ8f»hË?þœ#fgendstream
-endobj
-860 0 obj
+
+ÃÉÃìïéÃ" §çÿm0=?ÍÄú.Îîé2Ž!Ä0^•|"Üb͸YÍ™(¢Õv6j×¹À^ïÓ¬™lld²\WØൣ&-y©#‡Ä
+lÈ2*Jn¯ÞÉ÷b™£1~áì
+‹Ç7¸¾?žÝoZY»•úIY£¸Œä’¨G˜Œk9»©0<„ú\Ó³¨B’?JEÀ/Vë™>kõr|«tùBûîË":öºy¿›½Ÿ@3\@,ÿ7h†g§?AfܧÉ|A·~äö@ï@&¹XªT^¦oóån«6.Êœ RlÔª€šyyE‰ˆ¼5´.!©y²btþu™A@†õL%Ðv:éPG‰)&.¥„`€#G
+šG ßcùy¥@+ÊUý\y›5=Õð•ç¹‰Ñúu{›¯ û†Îƒf¦í98P&ñ}ƒ!H´\Z샨£°
+²ôyòMÍ‘ðwŸŽ—ªÇ5uWŠÈ3*Òå,]¹ü&#!¨J†yE›ü>óUõ-¤nN¢?÷*ÏŒ+}¼õœïhÆÅaÍ'<‘·w· ·Pã2úÎXGïÐq–¼;…8¯¥³Ø”à•KàýU9xøV•¾ãÙ¨”´² …—a|Ï,yÁÝël—Ooc=ÜÚìzbAcM™ió:ŠÅeÞ¥ß-ì{^óÞðô¬Ï߬ñ¥wçÛïâòîê’î­ñ]™˜¨dnðXçôª·Žª×z¿dëñÙ3Ìf{Ã~ ᯃ§Ç•Ìendstream
+endobj
+677 0 obj
+1654
+endobj
+678 0 obj<</Type/Page/Parent 635 0 R/Contents 679 0 R/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>>>>>>endobj
+679 0 obj<</Length 680 0 R/Filter/FlateDecode>>stream
+xWËnÛ8Ýç+.ºrD¶\ÇN t‘ôhÓ ìA1@6´DGlhR©8þû9—¤YMÁ4¨a‹ä}žs.õë$§ þrZLéÍœŠíÉÕêäÓêd’]\ÐóGs:ÏgÙŒf |ŸN³ j$m°+‹9~Æ•|Ša¶°‡~KùŒVø_àKÖ'´*FÓìMvžÑë›%}µö¡­_¯~žŒ?Ï(Ï㉳é'F—qÏÝè‡2¥Ý9º6^6Fzº[IKÙ<Êæî59|Q…$åÈW’ä¯V=
+i<ÙMx@ͦÈ'“|Œ)¹Zj£dI7W7Kv=¡³üM6e—w£鯮¿/]d”baW²!çm#ë±8¦¤ë[e‰‡¾ž*ÔÈ{å7®÷$(%3p\hÅ“Š!¯>ÜŽaÎIßÖT Gk) Ý«G|®–Â!=#c…b%ØÿeôŸ%ëÓ9Z‰´V–
+k6ê¾E@K±] ò69nCJ‹«·±ZÛ2÷T‹©!r2R–œm<R–Hßywì°:7rÛuÆŽâ㮡#Ú(-ßu{ßr“s:›žÇà(ýƒSG®­kÛxzOÿHwlæŒÏÌcŸ^N¨uÿ1#ô …y!eB.]ðÿ+ÚËÁ2’@(.ùqV6ïééé)ëýÿs‚»
+ˆIåvåíd+ǧGþŸaHzMÐäŸÐlñö™ê=>÷Ù;›gs$Ôçï,£/vGë¤d¤lZSxeÑ>¦A…%À£”µ¶{PE¬5Ú‚~$MÉ¿»b±  XKm°zœ*›Dñ£mbmå)}[v”¢­(*e@¾ŽsÜWÕPÇéHUº)ù.´< ^
+ÿýñv0(Jxõ­¸+
+eÉF?¤|ÚBC®Ö˜G§Ô Ù§®<0
+*©!þ!ÖMdÈõÐûald˜q0
+l8åÛ
+$„*†ˆ1:²ÞZ/û C²;Û<€B‘©ŒíWi›0ÆBä«çÉq÷zØß¡›Çc'UëôeøÒN¡›,íèˆf·‰æÀòòL¦8 yÆŠd´ä¢Ö¢xÞQ! —¦±-W ˆ“¯Zñ`ñe#ñò
+zJë–™éÂM×\ÆbâQ(-ÖJ3ðL›R0HõùaŸ˜¤xñxàë~÷¾1î d§»ú_šýáîæ J7ˆ5ãáw‘ÆǨíºÐ0§
+žª\Kù='Ûð;I!8mĵ«ƒ*(Aø…€öÒs×’eWáæ«€MÉP‡ÞðJ‚—º(ªãÏéœÏYNóyß–—ß®.鶱<Ìè£-Ú-Øòä`Îâö³ÅožåÞ<g‹n¡aC>ãS¸ÿuò/9šë©endstream
+endobj
+680 0 obj
+1693
+endobj
+681 0 obj<</Type/Page/Parent 635 0 R/Contents 682 0 R/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>>>>/Annots 29 0 R>>endobj
+682 0 obj<</Length 683 0 R/Filter/FlateDecode>>stream
+x¥XÛnãF}÷WæI,Ú”us€}¯g’Æž$V0»À¼´È¦Ô1ÉVºIy”¯Ï©ê&E3Ùd± ‚l6ëzΩjÿz‘Ò5~RZÍèfIYuq·¹x·¹¸NÖk:¸~¹Æ!|Ì×+|ÎfÉšœ¦‚_À3Xé?púêýœÒ”6Œ/×+Úäòüš6ÙäIU[E¾=¬k<)*´jZØjöª!U–öÅSa]¦sò§:ÛÛÚxÕ[Ù‚¶Ï5•ÆóË™³Þ“³mƒÓµn^¬{öÔzSï`O³ùå⚦éM2C “7NW¶ÑÔaóoè œªt£™š_"_m“ÌÖ¦Ô möÆS¦Z¯=…ੱ„Êy¡´™*©Rž„
+³cˆC¡»ô–ð òz­«’dêFï
+äÌÖú’¿f¥VŽýÐo0""GÞT‡ÁD‚&ôaH§Ui~Óù(Ó +šôôpG ˜Æf–6ð ²?ÔÀÁn~ÖIR$<ÿP*ÖCáë®nÀàìÈûDé”õa” •k¼ Š;µL€›|ò…=[ï t
+HÑá·F-S°\³Í"¼ÊÉ?þüñ#óÀaÀiˆê%ä >X+)ëbI[üíþÝ=ëja»Ò“¹zS©Á¬]‹:ª²Åd•’µ%ôxG)ìqô¢²Üª~Põ.n‡¡¾¾A­â2’òFòÓwéõž™³ŽT(Ñm²Š¿•ôÄûËp[¹™sg†2öoÛvÃÊé‚ùb¥ëœ!ü íÁúí:Y¾¶~^Œ$ lG]@cO?t"ð.-
+ÜÙ€|ƒ 7"7àñûOŸ7Ÿ0i \aèð ª,(”ëF™ÒCÏ%jS×Z”u¢è1È›«Rl\WÚ”Þ. 'z
+’MÆr’=Sz9Tx¸õ"î7É×
+¡Þ¡ q/ª_'PÊY(Àu¬b¯ÝÄÙ«#ÀËA`¹³‡üÓÚ
+ü“9 qâ ΋®™˜^Sejì¶h_?ã¼ ñ&$úÉdõSM£«æ•ëÈOØXž;,Ž¼·Ö#¯ÕTâcÁ<<ºÙ1ª«¯®%'zÙ›, ñ ÄÅÊÀ`µU[,µ{›9 d*ãß3{À>Ô·«ó¸¶’áƒáµË C
+qÆnœÑÁx¹äÐ)®7Îuå‚Š[îA粟q£,ûX‚ŽVZa_‘z½°úrœÞat'ÆfÀE¡ ×ê©®‘ºô†]Fjç
+endobj
+683 0 obj
+2036
+endobj
+684 0 obj<</Type/Page/Parent 635 0 R/Contents 685 0 R/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/F9 11 0 R>>>>>>endobj
+685 0 obj<</Length 686 0 R/Filter/FlateDecode>>stream
+x½WMoÛ8½çW |r‹F±ÇNÈ¡Ý6ØštÝ´DÙLDQ%©8þ÷û†”äXMŶ-RÙ"çãÍ›7“G)Mð7¥Å”Nç”é£Ë£OË£Ir~Nûv8vzšÌiv¾Àól–ÌÈJ*pŸ¦i2mß„Cá lá%ô?`èäjJiJË~çç Zæáý„–Ù¸qÒVBK*å“,ß,ŽN®fíé1ÕÂâ—–”#+¬,w„sURæ2Oøü„Ž§sD¶Ìǘ-ÞÚw¸çÜÖØœLEwןÿ"·s^jG¦ð¸­Å£$xÆGÒêYæ” |Ê6p—Á›Kˆ–¸ÔRTŽüFxRÁ ")Œmݦ§@
+Ö—.ÑV®@+kŒU¬h&umÍ|£«`ƒí±óåE/;¶F]¬Éð!j´ ²7¢]ŽPZûSÏe&—¯5¦FuìAô‹ÞÐ8äï€ÿÜsH À ÂSl®hV
+g0³â” ÚYËùÎ
+¯è(öÔǵ5M Áq¿@¼ôó•[}÷´ÝwIo!(-s$*‹¤ÑÛ†íºÑíz:Efg‚︰®2câ"cãÉì-æhƒî¬áâ ¬s d¸8ÒvÈšóÞ²U îå®—ÃîùübùŽ<Ço<Ca•ñ ¦#©Z<ø„àôÁÀ8{~IêŸùÅKˆNŠ.DL„H"×ÎÚóv'Nç‹$¥ùü4ÜÛ÷_>¼§¯Öýûh²
+endobj
+686 0 obj
1525
endobj
-861 0 obj<</Type/Page/Parent 794 0 R/Contents 862 0 R/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>>>>/Annots 39 0 R>>endobj
-862 0 obj<</Length 863 0 R/Filter/FlateDecode>>stream
+687 0 obj<</Type/Page/Parent 635 0 R/Contents 688 0 R/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>>>>/Annots 34 0 R>>endobj
+688 0 obj<</Length 689 0 R/Filter/FlateDecode>>stream
xVïoÛ6ýî¿âÐ|ñ€Z²äŸí–I“t»›C7 ´DÛl%Ñi;þï÷Ž”,ÇHV` àXy¼{÷Þ;~oEÔÅoD£˜zCJòÖõ¼u;ouƒñ˜šr…‡.ûAŸú㾇ø(%-±´KñÉ›¨‡}þbá-8~ Pxק(¢ù’ŽG4OÝ‚.Í“ö´ »–t?£ÏªHõÞÐdN©Î…*(Ñ…-u–É’¶F+rKg²Üá?÷¢+üiJ‚r‘¬U!I$‰Þ––ºäÅ?Í¿¶ºÔ‰zAŒSÛ3‘/ ~Þ%UnŠ¨þGÕû:w~݉‡À&òѾ&ísÿ¨Ší#™ƒ±2'ù(“­•o«Ýƒ*z›L¾Øcö)uJútóîŸÉÕý-u¾ÒÍôþêÃÄ=>“@JÛϤӉǨé˜Ðƒ‘¤—(YÊuêÄV%Â*¤šjiÐ¥ï[….â jZH|ÆŠ"eJ…z<àgôC—)¾X}†*ªR«Q¶*&‰‹~ ²‡H¼oÒ‘)-®™¥Ìµ•ÇÞß¼ ˆæ\DÝÈDØ~vâ"ÓÉ7Aþ›RîP$ez¥ œt Ò\¢cç ­’La[”Š•!³Mք쌴–Ù…õªØ‰ U˜µÌ2.¹âPxÉ8
Ÿ°)”6 }O}ãjª´ '•‡€ÿë¤U+"bYüñ¾Õï ƒ74ŽÐÂœú£XåŸ2š± »xäþž*å
-fV–Ú¹s½óÀsên £Qkˆ;f˜Ÿ‚È“>—ù¨xî
-Ÿ¸ÄEoœÚŒ=dq ã j<kÏLôÙžxˆ#XírN t#«ˆÞŠžJˆ 'µ¬]
-Îå~-Jª"ä.†~d¾P^)Oó’ªæ"ÑážA¶ƒÉÏ|ê0Ñà‡{]~;êì©*
-)!X^J'8¹Î!$®÷×,Z~õ›:ÛêFq2`&ó0îÂß뻈dCjcËmbÙæn§§þc*¼èoÕð‰»žéçþôÀžÏé50(ðÊ•t«Î¨rqÀÐ;…û‚ 5úC).‰Õå#Po3Ìiè½Bç¼ 'ŽÆb <Ãí&{ØàâˆçÔˆ#™2 ª ^ßʱ(<rÏå]óñÂÃ7¿Ž¡ã)\³¦NJ!W¾bÙ¨ôurª¿×‰Q†áoe?XGt‹a‰›¯†¾¥_6û_« µšüNn{âG)¼Ú_÷ƒñ³sVÇ‹7 ¾Ñóe±aÆìêþúŠ>•ú+ZJ7:ÙBäÖ]9ïŽßÕñÛÚÿoNöG}äæ.©qÌQ‘òï­,V¥Pendstream
+fV–Ú¹s½óÀsên £Qkˆ;f˜Ÿ‚È“>—ù¨xî
+' ç%<TÍM¢Ã=:‡l'“ú(Ôa¢Á÷ºüvÚSURB±¼”NpsCHÜ%î¯Yµþê7u¶Õ•âdÂLæaÜ…Á×—/ȆÔÆ–ÛIJ9ÌÝ NO .ÆXxÑàªéw=ÓÏ .
+èMŸÓk`:Qà•+é8WSåâ€9 w
+Akô‡RÜ«Ëf ÞfÔÐ{…ÎyAO,)Äx†ÚMö°Á%ÄÏ©G&2e T¼š¿•c9PxæžË»æã…+†¯~C!æS¸fM”B®"|ŲQé+êäT¯;£6 Ã_Ë~°ŽèÓW7^ 7|K¿lö¿VAk-4ù\÷ÄRx9´¿=.ãgn¬Ž®|¥çÛbÃŒÙÕýõ}*õW´”nt²…È­» rÞ¿«ã·µÿß ìúÈÍÝR£GEÊ¿·þj¥µendstream
endobj
-863 0 obj
-1423
+689 0 obj
+1424
endobj
-864 0 obj<</Type/Page/Parent 794 0 R/Contents 865 0 R/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>>>>>>endobj
-865 0 obj<</Length 866 0 R/Filter/FlateDecode>>stream
-x•TMoÛ0 ½çWÝ0ˉ8É1mWìÒ-z)0(²œ¨µ¥T’“õß´ì$: ³öD>ò=>½ F0Ä{ÓÒ D=¸ÊßòÁÍfp|Ø5~ a2Ÿ±1ŒgS|OS–•PR.bšÃ·Ç·s /1{6›B^´ëCÈÅeÊ&,e ƒ»%<)]˜½ƒûî¸Ø(-a!„i´w_ò—A|;>¤‰’ Ñóâ2ßH'#¸•o²²
-鹪 • aNý J&¡0è®OnyQ@ä ^)—¼Â’£âBîbÝT\Ô¡ß_š×òâùùsˆ´â1Ù–;·Ç\ÿãêUÆ!ªÏЪU5Í/hš ®½¤­€H7 8™dgf ®Uã”Ñ(E‚_)¶ÖìT!Iˆ²’¿Õª’PK®‘o¶È“G1c-­8„°ô\¯ Ž2ºCÅ"¸7à¶R(^ñIm-ezƒA9QÖ ×”^XIÙI ÜÆŠfí9ïT'îr€®vÌî÷ƾBeÖG»”îkÛ‡ÒkÂóÐé‰}Ñbâ VÖržbû8kõqHªñ ´ó’˜öµí ̸)ÓÊSë„ýF‰ 1QÌ„Á>C;ñP?Îsâ/m3 íñ­èMq0Ò9Úµ|N²i·Þ;’–£I¦u¡OKB7§ìw<ÆyrR4Vù÷Þ…µ¬WdÀ°ðpø;PoDâ•—Vcé;¤Ø
+690 0 obj<</Type/Page/Parent 635 0 R/Contents 691 0 R/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>>>>>>endobj
+691 0 obj<</Length 692 0 R/Filter/FlateDecode>>stream
+x•Tßo›0~Ï_qêöÐIÃByLÛU{é-H}©49Æ$nÁN±IÖÿ~w’(ê4 $ØwßÝ÷Ýç·Qc¼#˜Å0IAÔ£«|ô-Y–ÁñѬñc ÓyÆH²¾O&,…FBI¸ˆiÜÞÎ!Š /1{šÍ /ºõ1äâ2fS6a1ƒ»%<)]˜½…ûî¸Ø(-a!„iµ³_ò—Qx›ÒqŠèyq™o¤•À¼‘o­jdFWï°ßH K^¯8( ­Åÿ܇ÂÔ\i
endobj
-866 0 obj
+692 0 obj
736
endobj
-867 0 obj<</Type/Page/Parent 794 0 R/Contents 868 0 R/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>>>>>>endobj
-868 0 obj<</Length 869 0 R/Filter/FlateDecode>>stream
-xW[oÛ6~ϯ8@6ÌùçÒ{h»õi:Ä{ Ñms•H—¤â¸¿~ß!EIV4,›
-(5ÅsûÎw¿Íi†sº]ÐÕ åÕÙ‡ÕÙ¯«³YvwGÝËnñcF7 ¼–w·xÏ—ó솬¤ öÎh±¼ÊéÓõ"[ÆOP†¯°Ð¾ iúé--f´ÚÀðÍí­Šð+ùäãNì½´´Ìè£Ñµ­­Ò[úòþ3mŒ¥B9oÕºö² ¼ß¬þ:›Ñåb “\joEY‰*¡Å[DíwXU¹ðÊhÞͶçØζ/¯æð’ËlžÑ½¨Ö‚„.ØXܺ¤ù¼Ùº¸åïI×Õî™ ý¡Õ3¹£ó²rô0‘Ûwt_kº7¥°Ê=¼¹ áè Ë’ÿ ¢g<¼dS¿)]?_6ª½*ÕwÉ[›°æ )¬~)ëíV¬KIïOâ!úlŠº”l>?¼æJü‘¼¡½5OªD8\PX0V}¸O¬t¦¶ùÐvn
-üd7Á¸ØsÄR1Bرµ™ô;á[ìvúãÀ³û:ß!Þ|g€NcYé'S"Ê«§f€cÉÖ¬pï(y‚,ÍV5œmûnŠØ Qx± þ^èL³fiqƒfæ¡ìBH&¨’ùNh媈ŠôÐ2÷àHT‚«‹‹6ÖðvIµ.¤-¨æÝÓ"òÏŽšJo¬@̓aµ•`<RŽ`7ôÔ¸TÐB·;2-I•ÇÓO‰1(öTM wªŒuDÈ[xÁ´^ýx¾>’,”ç¤t¡PQµ(ƒ†*+  \QºIO2›ˆZeà ‘^¡)Ks¦€¶&ù,ª=ª>:9¢s:F‘›XÛŒEF´Úµ¤p'ÐAz³ç²u´–2£‡R­sSUè–ã|®ÑŽèTš÷5åÉy‘uÜrlšÁŠ:ѯC÷‰!îhnS—ØÅa…Ž–1`S%„Å6Y"£_ã&Z;»Ý³’¦µäc]*ˆóÕ8Î8BYE¦öˆ<—{x˜CrgNQí…¾ÕãþP¬3×ìié’Ƥz˧ÂÏu¬“óÁËËy6KÁàääú9î2p6¶KJh=íŸ!ÜŸR‹ªüæò ÞÓ´9„ö>”¡ôþØ„ÀÁ5½F\›àÑKáópn$K”Zì‰íyª÷ÿ.¹‡Zêù] U¾”|ËM¾ÈÚ8K«âz
-UÆÝ®-VªN¦.Õš«­â5ö…ùñÑrØIÉÍ2„ÔI$v=Æ9[G´`6·á¤Kè„ÕIkZ ¾4 ©Q3^ã|ØuCLš6øÞÆç\{ªó ÝT?ÆJþÄWt„ðö²Ü&Z¯Iv†'»v
-“4T])ÈæîÔô d&^1èÿ\*Ò8}:‚ų&ºÛŽã[C-vâ¦rÀ胎¡Äw½[çwlÌÿíVL¯º /o—Rpé.&‹%[Æ­ÿ÷³¿ÿ ÜÃendstream
-endobj
-869 0 obj
+693 0 obj<</Type/Page/Parent 635 0 R/Contents 694 0 R/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>>>>>>endobj
+694 0 obj<</Length 695 0 R/Filter/FlateDecode>>stream
+xW[oÛ6~ϯ8@6ÌùçÒ{h»õi:Ä{ Ñmq•H—¤â¸¿~ß!EKV4,›
+(5ÅsûÎw¿Íi†sº]ÐÕ åõÙ‡ÕÙ¯«³YvwGÝËnñcF7 ¼–w·xÏ—ó솬¤ öÎh±¼ÊéÓõ"[ÆOP†¯°p|AÓôÓ[ZÌhµá›Û;Zá;VòÉÇRì¼´t•ÑG£7jÛX¥·ôåýgÚK…rÞªuãeAx¿Yýu6£ËÅ:&¹ÔÞŠª:ÕB‹-¶ˆÆ—XU¹ðÊhÞͶçØζ/¯æð’WÙ<£{Q¯ ]°±¸uIóy»uqËß“nê5Ü3úC«grçeíèa"·ïè¾Ñto*a•{xsAÂÑ^Vÿ…DÏx>ÜÿBQ+xɦ~Sºy¾ möÔxU©ï’·¶aÍRXýR5Û­XW’ÞŸÄCôÙM%Ù<|~xÍ9”øyC;kžT! ˆ p¸ °`¬úp žXéLcó¡íÜ
+˜fíÒâÌÌCÙ…(
+LP-óRhåꈊôÐ2÷àHT‚«‹‹6ÖðvI.¤­¨æÝÓ"òÏŽšJo¬@̓a•`<RŽ`7ôÔ¸TÐB–Ö4Û’ŒFKRUàñôSb Š=USË:cò#¼`Z¯~ <_HÊsRºP¨¨FTÁ@KŠU ®(ݦ'™MD­³a††H¯€ÐÆT•ÙS@[“|õUÑ9£È›XÛŒEF´*ZRX
+´FÞì¸l­¥ äè¡ÔèÜÔ5z'‡å8Ÿkt :•GA‡fÄ}Myr^ä_·Ü›f°¢NôëÐ}bH ;Ú‡Û4vqX¡c e ØÀT a±M–ÈèW縉‡ÖÎn÷¬ä€i-ùX`—
+â|µŽ3ŽPV“i<"ÏåÎæPÜ™ST{¡ïDý¸Ûë̵{ŽôIcR½åSaŽƒç:ÖÉùàåå<›¥`prrýœw8›Û%%´ŽöÏîO©ÅU ~syPïiÛB{ÊPzhCààZ^#®Mðè¥ðy87’%J-öÄv<5»—ÜC-õü®…ª^J¾Æå6_ä@mœ¥uq=€ ®ç¹i´oÍØœò8–ÃðyUËó'rãA÷èÒÃÚ½|¦g,Uã’ç C_v ¬
+myzéðùñ<†ÇÌæE[)æ8²èíáç«`éL~…óÔ»Óø’Kä¦bиQyfïÂ@€sØÊ]%òÐJê8Çd(ÃÓˆ>
+endobj
+695 0 obj
1567
endobj
-870 0 obj<</Type/Page/Parent 794 0 R/Contents 871 0 R/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>>>>/Annots 42 0 R>>endobj
-871 0 obj<</Length 872 0 R/Filter/FlateDecode>>stream
+696 0 obj<</Type/Page/Parent 635 0 R/Contents 697 0 R/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>>>>/Annots 37 0 R>>endobj
+697 0 obj<</Length 698 0 R/Filter/FlateDecode>>stream
xÕXÛnÛF}÷W PQ
K£v¢’aãÍÞ©ê9sy*¡gD(«¨òäeÒ†9•+ŽWƒøiÍËR±*¶¤ IÊA0T^f2—ˆf¥p.ʃ® ý^¨ÇðgUÔd¶’9ÇKžÙò|*s×™$„¶4z§bws &¥;i,T왳`ÊŽgˆ« è}E‘(h#)Òy©2/–2RÉcŒø-Ž÷Hà¸gœ?ÑL—쮚dA¦.
å öÊú³mÖ{9èµ­J³‘QeÝÁð BÚÉÜÇ´ ÿ©Ø~ Åù°]’•Ò¹ë¨îRDÀçSi=#-²Éðßced¨H'N~Sbþ&ÅÊVFmjPЪ¹æJžÒx¶æ\Cß}ÿáæ~< &|€µ£¿¸ÏJð éòÁjp…Ì9pqºþÌôV¯àŸÙ©È¹Ò1)ê*¥Þ‘_jx·õ<E7¡BÇ2‡¡(ÒuQµwÐì¾AZ#öŸ i›R+åå–t}eÌ™XúnÆU™è,Ó{†0J#üLÚ¢©TTgÂWx,Qg¨:æáz·âmK?6SŽ~¹7çü_ÂŽk¼ß€“8‡™Ú„VFµQÕÁÕJã5Bù¹EÙTÄzO¢F,ž†Ô e;)­è´¶^(íë@ïÁë…róxá“Ü6É>ÈÞû ÒáL>
¾=¡»ºÀ`E£FCÍEŒGš‡¸;AÇ×Í[¹ÃA7˜ê*"—Ö6&Í æÊÇdR‘ë!=Ô ÌZ…¨é,&‘¡ì1 œV–Èàâ
`ôÖˆœDÓÞÆÓÚâ
-†Tv†¶DA9éQ*Š-ºNmÛ©Ó¨huü¿ðÞ8ú¢ŽùB ý·à}î £§ÒCð§Oƒÿ]É·®¥:Ô0OÑgFæç)F)—ŒesðKP´cÏRctl¸`´ƒæ)AØ0—•CžÊÇÛyÃ¥ªÔèz‹AŒóB>Ví3Ï Üigb@2ÉœÙÈl¶¹qÊ&P/ƒpô¯7#<ý£¯ÅXÂîÌBüVÇ4Ù"ÏÍPÒ n¥Ø¨ S\±b7œÊÍ“i‘ÅN]0ÉA™ë\6ƒ‰•™W-*½å’Î}Ÿµ–«yRÅÙ9GmªTT¾ü]8?HgSú-ïs» î
-€˜¡'vß]ÜD•‚¤Ûv;c½áÝU³ÔN—+ìÅËë©ß¿nîßÝУ?a•£Ûþ‚È÷Æþøx5Ã.ñèÅ1_ͱÁ¹Ó3Gª_/þ¬Ä®1endstream
+†Tv†¶DA9éQ*Š-ºNmÛ©Ó¨huü¿ðÞ8ú¢ŽùB ý·à}î £§ÒCð§Oƒÿ]É·®¥:Ô0OÑgFæç)F)—ŒesðKP´cÏRctl¸`´ƒæ)AØ0—•CžÊÇÛyÃ¥ªÔèz‹AŒóB>Ví3Ï Üigb@2ÉœÙÈl¶¹qÊ&P/ƒpô¯7#<ý£¯ÅXÂîÌBüVÇ4Ù"ÏÍPÒ n¥Ø¨ S\±b7œÊÍ“i‘ÅN]0ÉA™ë\6ƒ‰•™W-*½å’Î}Ÿµ–«yRÅÙ9GmªTT¾ü]8?HgSú-ïs» î
+º!Ž{…H)2õè•Ñ9üj#Î çmd£Š†à'ý蔓ž*]ží+ nŸm<¶üåv·éÕŒ±‡"â§>lÍþ J>¡ß~º˜_×´˜#|9M“àÿ'£þV £’ ô+Z,Œ.–ôqÄ«Ëîvz'‹ý(­ªòm:õÛ6Ûðô´»Ç§?¾ö±<\’èM›LÙ” ۵ж’²àTLÙËn ñÕÀ‹Çª[áA, h›_ï;Ná
+‚×Å–àœ[9÷”GrûÖ7X&öàj8ÚH‚(ˬ!ÍWαNµ0†‰€3Þ­¦©Ø1Ýh95œ(QÃpMÄ;ܱnw…*p®B æFè‰Ýw7Q¥ é¶ÝÎXoxwÕ,µÓå
+{ñòzê÷¯‡›ûw7ôÁèOXå趿 ò½±?>^Íð…K<zAqÌWslpîôÌ-u@Õ¯©®*endstream
endobj
-872 0 obj
+698 0 obj
1701
endobj
-873 0 obj<</Type/Page/Parent 794 0 R/Contents 874 0 R/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>>>>/Annots 47 0 R>>endobj
-874 0 obj<</Length 875 0 R/Filter/FlateDecode>>stream
-xUÁnÛ8¼û+Þ­P1’,ËÎ.zpš¶§m- —\h‰²ØJ¤KRqý÷Rr,¸vÄM“3óÞÌÓ¯YB1þZ¥´È©ìf÷ÅìöcFIBE|½¢¢¢˜ÅqLE9ß
-ó,KAOóÍÃö醤"«©æ†¸%2¢êK'µ"]ÓQV‚¸œ”pGm~ï]#”“%¿q†×µ,ÙMñcö¡˜ƒòUÎRÊÖ+<§ø7‚êÒ%ÙH)K'¤2¶`ôeóHﵪå¾7Ãýž[·c%¾¼@@.´Pâ?¾}š%¹Ì“ Wv”ÜÅl1®ZÚþUŒdy…\4¥%ɇ j‚J%o[Qш>½½£4ñd5]c7ÙÝdm ¼/äÍžÎä¯Yé8Ñw(ŸuF†ŽXOârExÂsFTë¶ÕG©ö^LmtGhiµR jD{ÀO ¾”á¢h€Ž’ªWTó‹öí÷MñoÀ¢(ÍC¹æßÑuÚònÇÑÔÔ#øžøF rš„â»V„ÚþpÐÆÁ^’ 
-wûÝ
-nœS¥k"HóŸÎŸnÞnPmx'œ0°_Û’rF·#¡3Ýc# Ï)íFj¶Ñ}[Q(ÌôM-KÝ+GènEVXëÝqÅ÷¢ƒ©’F ¸Ï²PÄJÔ¼oíDߥ6W¨Ð µ½¤úr–­@rœøí®³¡U{
-°8Ar¯4Jž)áðß„}Ö%m¸óÐÈTºò_.–øìh‘Äl5®F{ÇXúLã4tŠ·G~B¦pÚã9_…v÷N)9d!ô#î ¸Ë;Äj`áq§kìæëŽaw²Æî:E.g_ ÂYæµX«4§ƒƒ-¬Åª,½£“ø,`dY4Ú·k¬d4
-¨‡ÒcÓ0(ƒaòWðz¼'ÉWÌ¿/ð:˜Œàíæñ~C_ŒþDЃ.{Ÿ0‡ýí˜þT4›ÿ¿­2¶Æ;ó%ÍGŽ_g
+699 0 obj<</Type/Page/Parent 635 0 R/Contents 700 0 R/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>>>>/Annots 42 0 R>>endobj
+700 0 obj<</Length 701 0 R/Filter/FlateDecode>>stream
+xUÁnã6¼û+Þ­°b$Ù–=8ÍîžRlk{É…–(‹[ŠtI*^ÿý)9¼Z1DÓä̼7óôï,£­sZTu³ÇrvÿiIYFeƒb³¦²¦”¥iJe5ß û*+A/óíÓî厤&g¨á–¸#²¢î+/&ÓÐIÖ‚¸œ´ð'cÿ!ÞûVh/+ã-oY±»òÛìc9ë‚å´Ü¬ñœãß
+jJ”-GJËœáqBjÁŒ¾lŸé£yèípàÖíY…/¯ -”…¿?ϲ"
+÷U8‹X‹†÷ÊÓ^´üU{ƒ
+ÝPÛ»Aj(g¥’ãÅw› £Õ9ÂâɃ6(×øj¤„Ã?bô§ñ(iË}€F¦òu(øj±ÂgG‹,eëq5Ú;Å2$`§¡S\ø™À]lOà|bØ=8¥â…иS$஫EÀ®±[lÞ8ÆÝÉ»›A¸ž}7™·J`­Êž¶p#¨vô;Åd#Ë¡Ñ¡]c%“àÍîaÖt¦î•€•¹º87£ ¹×q
endobj
-875 0 obj
+701 0 obj
822
endobj
-876 0 obj<</Type/Page/Parent 794 0 R/Contents 877 0 R/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>>>>/Annots 54 0 R>>endobj
-877 0 obj<</Length 878 0 R/Filter/FlateDecode>>stream
+702 0 obj<</Type/Page/Parent 635 0 R/Contents 703 0 R/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>>>>/Annots 49 0 R>>endobj
+703 0 obj<</Length 704 0 R/Filter/FlateDecode>>stream
x¥WÛnÛF}÷W Ї*€D‹º;@
-ØIÕä!(Z«ŠªKr%nBrU.)Eß3C.))M‹ à˜ÜÙ¹ž93üë.¤1þ…´œÐtAq~÷´¹ûqs7V+ê•{<Œi2›3š­–øûa…?KM;¾C¨é~Aü~ý@“1mvоX®h“È9Þăש:Tº¤y@o­«L±'EïM\Zgw½1®*MTW:¡µÉô‹ÍÇ»1&3(<Ÿ]¥sªJ­Éô¬òH±
+ØIÕä!(Z«ŠªKr%nBrU.)Eß3C.))M‹ à˜ÜÙ¹ž93üë.¤1þ…´œÐtAq~÷´¹ûqs7V+ê•{<Œi2›3š­–øûa…?KM;¾C¨é~Aü~ý@“1mvоX®h“È9Þăש:Tº¤Y@o­«L±'EïM\Zgw½1®*MTW:¡µÉô‹ÍÇ»1&3(<Ÿ]¥sªJ­Éô¬òH±
ó™(Wqj
MÛç#uRHTœø
†gLA׆»šzPôa{¯¯kŠØe¢ç0Šûµ§‹q§çš©Ë4ÍÖ$ü)|2pypøµ¸ àz‚lÁÝù’³&OmžzÝÈØbŠãËœ1uô»­ œcö…ª8i.e)&!^‰–m$•nN)ÓG}‘½ àÎj†^¹r§þËìMÑË­“$©7­]þ5=vÞó506«ïÑså™Y­ÁžÊÉ­ÌŸœ/Ó¡;ç‘ÍLLÍ©pêÁš¢"n¶–×…®!.ýYå‡LÝâxoüJ“@ï~Ý•˜>Ö…Ì’ÑùË–+ÃíVr²²¾®vó¢2}`àvÔLÀ³…ôz}Ó{Šþê‚ZéDU˜ƒ‡ŠƒS1ø¿ÑäµH†¬üLŒ—R7–Á|ƒz’÷C\%¨6·ã)Ñ i‹ŸÛX·/¼·ž09žÍ2Ž„“ˆ‡QCE˜F‘x*,U±ç‰ÒŒ½¦Hxd=ÌÙÏÉx<¾5ñV—ú{©àc© T¿%úÐö…_T‹Ð 3(ãr>ðb«`òÓGÎIÛÀ2¶_z\`b‘?Vúóæ5µ?˜»‘±Ž
P½¢çÇ÷O_•ÁÑ4AôÜmî6•ìÜ×ìXýÝcÙ²º‡$sÀW,õÝÙÛéÑ9B¦²½køìFi·³œé„äh0Í°nŒú>³tÝ\~ñk;Ö÷ïqíle¯¿kÛ+ô 'ÿØ7ÜÇh.R¼‰åýHs›Ðr>ÿîd\C‘ž(¥‘˜Ä%…íöê æ¿t¥Q ýÔ)6ݽQ¹Ÿbx´¸ÔÖYâk˼pÐeno}ÍÞŠ„b3M *u—%®HL¶÷žÆd¹:æÅ[­-²³‡f»ívà TÔ,½¼Ä¥Æ|bÔe°$‹ebvg1Ø Xˆ“#s–
¡ÆèšO¤ïœKØæÆ2va]2›hv,v™ÉM³‚JðÑõœ“ª#,þ® u´&Ÿ%H°GÏ
-°gå‘ÁD–,áÒ½pE ó¦%›U nd~Ú²Í7~ùoOjâ7[ÎÀMø¨J“%¿ÀÖñËÝß‚:!}endstream
+°gå‘ÁD–,áÒ½pE ó¦%›U nd~Ú²Í7~ùoOjâ7[ÎÀMø¨J“ ¿ÀÖñËÝßgc!uendstream
endobj
-878 0 obj
+704 0 obj
1534
endobj
-879 0 obj<</Type/Page/Parent 794 0 R/Contents 880 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>>>>>endobj
-880 0 obj<</Length 881 0 R/Filter/FlateDecode>>stream
-xuTËnÛ0¼û+æVˆUKqü8&MskÑ".zñ…&鈉Eª$eAß¡$'¨‘Z0 ˆ\ÎÎcùg’cÎ'ǪÀͲšÜo'ŸÈsl\Y®WØ*̳ù|Ž­œ>+ŽÇAG45b©ºjïŽFâhìk@t¨±1½¤eX[ç_Jáu@ç´ÂÆk«¢ðO¢Ú‹ìjû2™cV,³1§¿‚öÎâáf¢e1äÑh¤°°®ÅÞ»6膛½&+n&ûô'í!"vü…„³Û©CÈp'¥ÁØg èùMV$ôDFÀù~qÝ´-,!êZ ž Œ×2:oÈi¤:´·»¢xåç¦g0l¤fã.á]íˆÔnÐdhù¢ƒQ·^–¯Û -À²¸¡6‹õŠïÿ”ä08¶ANÑ’c·ëM¶üdzÛ,çƒï.ê0Þý¥å³"<ým¬¢–o
-[­Ujx¯ ²w,U€9@ öúd\H¨rM ÖÙ5ØÀTBinMßàYL/ȌԠ3AÐ ¢ÄH—ZÑ¥jÂ2?Þ©†{D
-P;SQZÆ‹'€t~†—s;[ekœÜËÕ¸~ÎuZ~ËÙ—Æ{¦*Tj¯?b2¨ÑMï ÓS…ž ³ž‚+*úJ×8I§£kµ—"è»áô¨éÿZ9·úȼ-ob‡ºñµ :\TǸu€`_Œ-3˜4ô=ôïç!;+ÅIõ–:—¦f¥U>ÔÚW†cà,ép¦CZòu–z(̳eNÕå4wt]™C/Öåè›aòΓÑ}(Ä™ë›c¶› ýQ¶ieåËU–nª$åûôt÷íþ?¼{á8âÁɦ¢›"Y—¸Î†ªÙP6½œ…ÅjÁ,ôæë´ŸÝüœü¬úendstream
+705 0 obj<</Type/Page/Parent 635 0 R/Contents 706 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>>>>>endobj
+706 0 obj<</Length 707 0 R/Filter/FlateDecode>>stream
+xuTËnÛ0¼û+æVˆUKvý8&MskÑ¢.zñ…&鈉Eª$eAß¡$'¨‘Z0 ˆ\ÎÎcùg’cÎ'ǺÀbYMîw“Kä9vG®¬6kìæÙ|>ÇNN§S‡ #š±Ô]up'#q2ö% :ÔÎؘ^Ò2¬Ž­ó/¥ð: s Zaã-„UQøˆŸ¢:ˆìf÷<™cV¬²%1§¿‚öÎâáf¢e1äÉh¤°°®ÅÁ»6膛½&+n&ûôgí!"öü…„³ß«cÈp'¥ÁØ' èù"+z"#à|¿xÀ~Ú–F–u­Ï PÆk7ä4RÚÛß
+qáúªÅ˜íåvËD¿—mZÙßFùj¥›*Iùv#ý¼ûz‡ïÞ=sñàdSÑM‘¬K\gCÕl(›^ÏÂr½dzsŠEÚÏn~Lþ©pendstream
endobj
-881 0 obj
+707 0 obj
687
endobj
-882 0 obj<</Type/Page/Parent 794 0 R/Contents 883 0 R/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>>>>/Annots 57 0 R>>endobj
-883 0 obj<</Length 884 0 R/Filter/FlateDecode>>stream
-x•XMoÛF½ûW rb
-eùBÜÖƒÛ†º†¿n ‡DÎ:oÚ}ïz¾J9$7ªt½¿%Í罿Śï~Ô;2VlÜ©j£h‘ÎÒ%y]jÕh2ÜRSÂ2mrdŸYi´Eî­C,š5ž¬jÍ“ÂÁ‡¶Eœòœ_„<C\´qÿðëô„Œ%ÝÊåf»·Íµ/÷/åžÆ¯-çáZö¯ZüCÐ1`|Ì”×Û®$ëpÏQæªÚ;tN“øˆU#·•k)ráš–B=`ÁwÖr Ξr„±¾}MkÊ’ÜFï៸[Sj:t
-JÍ•Dxª·K*¯Œ¼jQÕLY.”¤us¨èÑœ?}y²XÏÒ5-/ߢ«-.×鼿*鎱;Ã奴ü€Ù¶÷ºÊU‡æp¹Þª®léI•ŽéS­¼ª4óD(cW],.Ò7#ÇãkÜ]]AÆ°Ž3ñt~»èQsš†MuÊJjººv¾•‚f¤4b&‚9¡B5´ÑÚ’pEç´E‹ùµó[P\œ ðÛª²Ñᑃàãø­¤õÝô©Sj€×JYSw%°
-#' ¼Ôg¸Ì~Ðδ…`ěǢE²Žé½éÚ–“… -`Œ¹¹ñ:„÷¬#ÝxÁ¶zJ•Ü³0”ÐÀ ¯~ýx ¼µEJß 4AYiÛQíê欫O98DÃù^HhÕ74ùìŠÞ=Ѷ„ IG´
-endobj
-884 0 obj
+708 0 obj<</Type/Page/Parent 635 0 R/Contents 709 0 R/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>>>>/Annots 52 0 R>>endobj
+709 0 obj<</Length 710 0 R/Filter/FlateDecode>>stream
+x•XMoÛF½ûW rb
+Ñr®eÿªÅ?ÆÇLy½íJ²÷e®ª½Cç4‰X5r[¹–"®i)Ô|g-Çàì)GëÛçÑ´¦,Émônñ‰Û±5¥¦C§`¡Ô\I„§z»¤òÊX Á«UÍ”åBIZ·'Œ:ÍùÓ×'‹õ,]ÓòêºZÑâjÎû«’î»3\^I˘ýh{o¡« Qµqh™ë­êÊ–žUÙé˜>ÕÊ«J3Ð9O„2vUÑÅâ"½9_ãîêj2†uœ‰¢ó»E˜Ó4l²¨SVRÓÕµó­|0#¥3Ì ª¡Ö–„+:§-Z̯ßâ‚ø³àl€ßV•ì
+É*²ÐµVm  .ˆ5§1ÒÁÖÕŒ&ÿp™dx?Rôó»¦)ÝH]¤,ˆ\¬ƒÚ{ׂëF3Å=þ‡ž5§SÓ_cä'É‹GéºË +ø‹YO&!ÞYí›ÂÔ“‡_–üE?â&ÂNËQž@£X{ U¯êIÓ5xô£Ó  G5Àˆâ[”ˆÅ¿ÐeŽÎ…Ñ`&qœ£n¨ºÖÊ“ Ã
+~Þ
+2䧦$àîq‹ÐP
+{¶ílÆÂ¥ÊIúBüHbQ‘@#¼ØšJcþ7Ζ{â(x²ŒŠÿÐöËÈÑëá¼Gíä¶`iñÈ’íõ¥¢c„ÄÆ9ûƒÒ3ÀíXN˜‹«ÿÓÅj9—éÅaÕ
+zö:|ñâ…]àµtß ð
+1p6¦=’™6²é²d»Ìá]áÈíl¨ô$ÓJ󹕀 îh?)ÅÈÌGmúE»ZE¿÷ƒóè¦7÷·_ÿ¸ýúø(PzL~cub;o'±^‚LcP›qˆ'ÁÐ4_F ãQ·ï?~¾˃½D;Ÿµr3˜ãx~bLB•\£šË¶&_£hüÖˆÊC ¹³²¹M#?Êú'>sÝdÞÔa¥myFÉWì¨ü™sì+Fp¼ÅðËû­zÓ‡ÛckXŠú>…­^5ÍÎùœr5ÇæýøöHåcÑbÝ”B8¹ŸÐà¤#ìyèC Tà€AâŽ÷½Ãn–¼ÜÁÆ,†Y¬«ÌÆC\³’×÷ª8Þ$ p.èTè×
+endobj
+710 0 obj
1797
endobj
-885 0 obj<</Type/Page/Parent 794 0 R/Contents 886 0 R/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>>>>>>endobj
-886 0 obj<</Length 887 0 R/Filter/FlateDecode>>stream
-x•XMoÛ8½çW t‰
-¸Š?R'ÝË"I“EmÚm¼ír¡%*f#‰Z’Žãþú}CJ¶$·
-'¤É™7oÞ<æߣ ñoBgSšÍ)-.G'7§4™Ð"ÇÊüüŒ“ñxL‹4^¬¤‘¤,‰Šî”®ô¦¢T—¥¨2r+áh£Š‚6Ú<á“[ѽ(—‚°=#QzC‚ÖVš°x‘•ªRÖá´¡Ú¨gUÈGùjñíhL¯'³dŠËãTW•L̈œÆ÷ÑÓdœœŽzÆiÂ’ÑÚñzºÕ£D,’›4v¥jÒ9QŽ³-銖q *t*
-$qs–¶ÖÉ’´Ünd©¤R¯+ÁïÇ®&Š 1Ë„+@¨< Uˆe!9¢ZÇ7s(|èÉͼÁ5¾—i¡–Ío[´cFÔÊtm”ÛÖ0[Úà''õvØŸ¨D¹¥‹¢PYqŠ|S@g!E9ê„“]úåR¨ªÙ“»š¬r2ჯG(2ÍgódN§çgø „ ÅÎ'ÞÒä´áÄxšœ÷X1ONú¢äFUL(SUÓH¡–¦TÖ*]Ù€C›1Š<e~1­2-×Î!`¹‡íM [ôiRÔ?*n¾™ÐU¡Ò'ÇàLKKƒŸ,­k=S¢Ð À ÖÀV c3‚/@Ü Ü3˜CúûîöŸÀ¬¶¶L¬^  ý8“LÙº[°Øó¹6%ýh“c,€#£Ý_þrýùáÁwÊCü^#›J”òáÕ ëΗ¾úÎ gN[ÀÂAC¤p碌¼ýxïOÐ'´Õ¨!èî8Žç'‡ùP9ÆÝI¨Ðë+Íßê´4:3˜±O¡ƒÈ{YÿäÎLÚÔ¨Ú¡ "Â5W™¬œÊ·ü™‘n¬
-Ê(t.U@Àöí—+c]Wîfogh¹_ËÝìÍ[Hbw²ÜMºá«;ŠÔ¯+Óc§mÖâÚ5ÅÉ£ÑëúÄÝÀÝšg¨éKµ1ÒֺʘǑ‘"‹Fñ(üA¾`Jàã/Gb"€RÔ5Äg¹m„_U~Žº•‘’d!KàÏl¹¸zOa03ºÇæxDÇüÇq¿ÓR9ÛæÏÀ¶ÞýÈùÐNmxN6òî¬uõg{  ½ôCš<\áP¹er¿ñýΦƒ­²ç¬0,ýPî]Ýì,‡ùè:Ñ6zÏ8ìâè¨Yï¬áЉÁ(õ#;ÙΘŒŽÇú‡_ veWü7™1¸CßKMNÝ´!kƒrõ"ï ÀHí¨êcòyü‚éPmÃÖýY01 J¦«cÇtܲ/ƒID~L j˜Â†ÙF+Û¢Æí…Ÿw ](á`k”C£yi¯Xƒk˜!qm×~X0
-û¬ìNk#sõ:Š÷ðt8ȃ¢{”vƒ.ÒTZ{iã€G#Pž›Cˆ/×°ÔìTVÜĘš*̯{+ÀWé^ŒÞd3ß™ÌÂ{P•® Ñ0ÛÏC_Kv,žçДV„ßé¶Òd0l¬ÿõ/Œx‰§‚rÜ ¥†¦+Dà±lì¿Æ¤)´
-¶{1ÍÙ˜‰Û=¾È†×
-endobj
-887 0 obj
-1782
-endobj
-888 0 obj<</Type/Page/Parent 794 0 R/Contents 889 0 R/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>>>>>>endobj
-889 0 obj<</Length 890 0 R/Filter/FlateDecode>>stream
-x•WÁrÛ6½û+vtRfÙ’mÉéÍ©›i&MÜ6ê´_ ”“¦õ÷}»€$
-r:ÓñØÖˆÀâí¾·ËïgSºÄÏ”3ºšSV½_ž]|¸¦é”–žÌo´ÌérryyIËl¼Ühò:³uŽ-Ù‚rãtÖZ·¥F»Êxolíi£<Õ–œV%UZÕ¦^™šZìÿëËÇŽ÷Ö•9)ÄtºqÚëºõo–ßÎ.éíôj2€1ïã¯.>ÜDlc™z£iu>
-v°ÇGÑÛj|K…)5e€„Ô›v<
-ßt%œUÊîL\2¼X;Û5Áã‚öR  &ÌÍÍýKèØx2º£ê-üÌAúß;8=õºLÙ‡K€Ø0·“#
-&ax}‘ih?¢‰æªýÜý…‡
-endobj
-890 0 obj
+711 0 obj<</Type/Page/Parent 635 0 R/Contents 712 0 R/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>>>>>>endobj
+712 0 obj<</Length 713 0 R/Filter/FlateDecode>>stream
+x•XÁrÛ6½û+vx3£Ð’lËN/Û±;î$N«I¾@$h¡& €,«_ß·
+ÚhóŒOnE¢\
+ÂöŒDQè Z[iÂâeVªJYg„Ó†j£^T!Ÿä›ÅßGz;=If¸<NuUÉÔÉŒÈi|?9K&É)᨜&,­¯§+Q=IÄ" ±IcWª&å8Û’®h©— B§¢@·aik,I›ÁíF–ÚI*õºâü~ìj¢È³Lh±$ŒÊ‹P…X’#ª…q|3‡Â‡ßÎ\ã™jÙü¶E;fD­L×F¹-aݳ¥ ~rQoýŽJ”[º,
+e‘§È7tR”ãN8¹Ñ¥_.…ªš=¹«É*'>øfq„"ÓüdžÌéôâŸ0¡ØyàÄ;šž6œ˜Ì’‹+Î’Ó„¾*¹QÕ““Ê”AÕ4R¨¥)•µJW6àÐfŒ"Ϙ_L+D§LF˵sÈXîa;ka‹>ïOŠúGÅÍ7º.TúÌàœiiið“¥u¢gJú xÅØjA`ì`Fð…ˆ;{sHÞßý˜ÕÖ–‰ÕK8!¢¡g’)[b ö
+½¾Òü­NK£3C;ðê0ˆ¼—õî̤MªZ "\s•ÉÊ©|ËŸéÁ
+€C~¶@~»B1ývs 0r%‹¬­¬O¡ÖBÏ2Ê„KaQß1ìïB“£á€ƒ ’©‰´ »®kmÜw²±ÒkWX{õsQXOɽ"ÇœUC"O;–¸ ¹´
+^¡=œ;Ôd_°ÍZ]n []É©â×».éÞó£Û5ÔþZWÎè"²@Ý
+Øö"Sy«œ¯iDÚÐꇒvLVÓÝW…’#
+Np#PPF¡sÉ ¨¶o¿\ëºrwòî-÷s¹;9{IìA–»iB·|uG‘úuezì´Í:P\€C»¦8~2z]ƒX ¸[óÌ
+½ôCš<\áïP¹er¿ñýΦƒ­²ç¬0,ýPî]Ýì,‡ùè:Ñ6zÏ8ìâè¨Yï¬áЉÁ(õ#;ÙΘŒŽÇú»_ veWü7™1¸CßKMNÝ´!kƒrõ"ï ÀHí¨êcòyü’éPmÃÖýY01 J¦«‘cº@nÙ—Á$"?¦ 5LaÃl£•mQãÀöƒBŒ‚Ï;.”p°5Ê¡Qƒ¼´W¬Á5Ì„¸¶k?,…}Vv§€µ‘¹z Å{x:äAÑÊ»A—i*­=ˆ´ñÀ£(ÏÍ!ÄWkXjv*+nbLMf×½à«t/Fo²™ïLfá=¨J×…h˜í硯%;ÏóhJ+¯t[i2 6ÖúF¼ÄSA9nRCÓ"ðX6ö_cÒZ
+)Œwž
+¢!–èÔ0ð{6­É¯½À3èøö¢1ªÓùy2ÅŸ
+ØKáùòpùñê’>ý7ƽ×éš †pà&‡ò6l{>Ã_²øÿ½OÏOñöô_œñix·þqô©B6¦endstream
+endobj
+713 0 obj
+1783
+endobj
+714 0 obj<</Type/Page/Parent 635 0 R/Contents 715 0 R/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>>>>>>endobj
+715 0 obj<</Length 716 0 R/Filter/FlateDecode>>stream
+x•WÁrÛ6½û+vtRfÙRlÉéÍ©›i&Ý6ê´_ ”“¦õ÷}»€$
+r:ÓñØÖˆÀâí¾·ËïgSºÄÏ”3z7§¬:û°<»øxEÓ)- <™ß,h™Óåäòò’–Ùx¹ÑäufëÿZ²åÆ鬵nKv•ñÞØÚÓFyª-9­Jª´ªM½&25µØÿ×ý§Ž÷Ö•9)ÄtºqÚëºõo–ßÎ.éíôÝd
+SjÊ
+Ò(§* ”±ïf»¾«!Ƭ$ß5umZ9V!ŒáØ‹Xɸ
+¯+mï»8_~|¯Tö$ß¿ryÙ:ƒbxãF¡ß¸q˜Gଙ*97ª"³Uck$™ªèÖ‡'ú£jä¼GntN£~$ý7zÑÊ´x\pCF¸sAd|ØáÀæ}—ÁïÒit§Kø5¢‰íáôƒÇwÏ;ˆ'lGJpG™umžˆÖ@‘È’’㨣n¿4ÿ9\ºewª›Õàbçœã¬ÈË9Óáj8]Ðßñ<‰{Uå†öè-¨TBA® Õ•¸†"h¹ìp3`¾ór—J`Xõ~ÈeˈÄÙ{¶r¦½W0*þPu°å®Î6šÕì©HÿÔ˜>²ôB¦„è¸;FÐœÈZ¢ÃãØöø ôÂÞù4&F8õnPI?mý”˜Ð½¨€ß°Üƒ–¹7Žê.¥èÔœi¯é )ŠÚR´¿YoJüÊ ˜0rØÉŠ¤ðƒr{T%\•çpn'JáÊB"¾rBƒò#ßè ·Å AKÌ6 °‡¾Æ%»1ÍÉ™Þàð‡ÉŽsRøÓÑÊÜ—CçÂCœ±§73¼±ü÷Œ=½º‘ŠÃkÕõd‰fBQ±T0™Ãë‹LƒDûM¬à0Wíçî{äò“é0g\slˆ-¢°¯ý <À‚
+N"“:G–¿]Ìð&›ÿïkÍÕâ
+ÇÈÖÙœãð?Îþ²ãÓcendstream
+endobj
+716 0 obj
1613
endobj
-891 0 obj<</Type/Page/Parent 794 0 R/Contents 892 0 R/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>>>>/Annots 70 0 R>>endobj
-892 0 obj<</Length 893 0 R/Filter/FlateDecode>>stream
+717 0 obj<</Type/Page/Parent 635 0 R/Contents 718 0 R/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>>>>/Annots 65 0 R>>endobj
+718 0 obj<</Length 719 0 R/Filter/FlateDecode>>stream
x¥XMÛ6½ï¯ä²°«•ü½zHФŠ4mãc.\™^3+‰Ž$¯×ùõ}3¤$Jv¢E€$’Èá|¼yóèoW Åø“ÐbL“9¥ùÕÛÕÕÝû1% ­6ø2_.hµ¦8Šã˜VéhcËTÓÚ”:­my¤J§ûÒÔGÊíZ¿^}Åæi»ùv<¦Ø>úT`“¢}¥KJ3“>UäÖÎüÚÑ«O¿½êoQmIívÙ‘ê­&Úé27UelQÑg•?(ÊÕ®’oæY½¦àÍl0¦ÛdÙ >þî±´ûÝÝÁ–Ùš¨¼;ܽP]š]¦J}CªX³É‚&Ë(ÝêôIŽH·ªxÔëÞ!È‚¢Áfõ¨LQÕ²öÁÔ[#S°ïVWœ>É!%ü¿¿~½Jæði>aÏrZŽÛ‡Œ>s øÉT¼îRÏYðö‚ 9%ñ2š{[Íöþyå#u5õ'­•TÕ“d®5"î‹‘¦¶#Ú©RåºÖeDoŠ#IÌõVÕD]jdÎåK^)¼(l-9A]®“k¤©2Ug†xQ¦75}+N¶…S™-€
IYká"*Ù×]iŸc¥[g¼ETjóªÍƒÉ˜»¦ÞzNG1(‹[±ChË;>Û´Q©ß‡ðÁ4¥]ïS½ŽhÎáú6TwRd¤ÙyQ[Ð!¨&[À sËË}¿[8¾x±Xø9ó³j>‹!”©ü랺ÊÇL3!™ÿ®_j·0cÓ¦uCgÕõ˜N"¨.ÄAx~NSÁcß›¶Š§8@(dè+¹ÉÓô«0@ÓåRà.ÃÆ=´1O—÷½ˆ›)ÕòE܆ð@n§Ü–Ú²ÔÕÎòÜðLã[å<Í ÏI,gH
-"S¸SŠ7Ìd2]gW[ðS“UC‚¨j¾oŠzä¾å«*Kë–Y)¢8'r«0 \ãòh÷¾ÏNíw|‰awÀØ-çVþÔÍžo¾–um&—.GîžNN¼@€pΔ¢UÁNÅzP‘ÑFËW—ÕUq]{E§p{DçÔ&Ýgªôw*()‘B"nø
-endobj
-893 0 obj
-1657
-endobj
-894 0 obj<</Type/Page/Parent 794 0 R/Contents 895 0 R/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>>>>>>endobj
-895 0 obj<</Length 896 0 R/Filter/FlateDecode>>stream
-x­•ËnÛ0E÷þŠAV«–íØiwé (Š6-¢ ]dCStÄF"]’Šá¿ïêUuvE6VHÎÜ9s‡ü=IiŽ¿”6 Z®IV“·ÙäÕÇ¥)e;¬¬¯6”å4Oæó9erzí)W^:½UùiC·¢Ú
-Z$ódE¡P´NT*(çéÍyö Á}°Ùb]Y>•N‰ ¨þ‘÷Ì©_ÙY'uë6W£õ\;%ƒuÇ—¶´ç‡õ™Ê)ª½ÊQ…Jädwã
-ríeíyOÝ kùM
-Åî÷Ú<4@Ÿ»3[pw¦M°Ç“·•ê
-ys;ˆ±ÕÁÓýÔײ áé -ȉ¬)g÷ç`lr÷õÓOÚ+Wiï¡Ðs0A¬'¡¬Ð¾íGºDùH])=h<
-ô¤ES¾’µÓáH”kQÚS‡FÙ9Äö7ŽˆµÀjOtλ1Š‚hû¨Þ>uW)
-CÈ7; ž5§fͱéÿ¸üW›Ur…§7ïrÉ9ð}Ÿü_¸j³endstream
-endobj
-896 0 obj
+"S¸SŠ7Ìd2]gW[ðS“UC‚¨j¾oŠzä¾å«*Kë–Y)¢8'r«0 \ãòh÷¾ÏNíw|‰awÀØ-çVþÔÍžo¾–um&—.GîžNN¼@€pΔ¢UÁNÅzP‘ÑFËW—ÕUq]{E§p{DçÔ&Ýgªôw*()‘B"nø
+endobj
+719 0 obj
+1658
+endobj
+720 0 obj<</Type/Page/Parent 635 0 R/Contents 721 0 R/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>>>>>>endobj
+721 0 obj<</Length 722 0 R/Filter/FlateDecode>>stream
+x­•MSÛ0†ïù;œÂ qãHÚôc¦Óii3í‹"+X`K©$“É¿ï»ò®n.1’vß}ö]é÷$¥9þRZ-èü’d5¹Î&o>-)M)Ûbår½¢,§y2ŸÏ)“Ó+O¹òÒéÊÏHºÕFÐ"™'K
+…¢p¢RA9OïN³G[ôÁf‹KìÊò©tJE•ðO¼gNýÊÖ:©¨[·¹­çÚ)¬;¼~x°¥=?,¨Ï´WNQíUŽ*|P"'»Wk/kÏ{
+ìNXËÇlt±\& Z®Wøâ ±¶ »·”¢Ffw‘2”!½‹d•Ðg:Bm íu(bR„É…Ë[ž[]*!€s P(v·Óæ¡úÒÙ‚»3mz€=ž¼­TWȇ›ÛAŒžî§¾– O'hANdMy8¹?ƒ`£»oŸÑN¹J{…žƒ b= e…öm?Òs”Ô•؃Æ€†hÝ$­Ù–Z|…½R¦áÚ¥¨Å«@ÏZ4å+Y;D¹¥} Ð8vh”ClqãˆX ,¡öDç¼£h/øˆöQ°/ìžêáSw•R@ÆRd9 )•÷D°gÌf÷F9Ò ,KêbôX#U0Éåù虾ôÅCÕHèÎ Y¨ ¥lõ¶l 5Šð44PáCf¬Ü,µ<G4bòÐ
+c¹eœ2šz0€?9VO‡ÛËhbðá
+šÚe!̃j² íBð‘(K@ÅÞÊ«ò›† k#óâH›ï,ÐTyFzò±o>]´—È”Nn¾œðÑ—¡žrζ‚Oü›Uöœû)Š„;ƒu3¯ä9–Ë FÂ;½È
+ÿËZO@눾êD2“C ã4„=í™<9îC´|‹æý‹®QpÚL(u3‰@b‹»†0&¡ÿ5×<a1¯4@{ÈÇŠ?ÂxèÞÖ›[ð`8ê2‡'0vž
+ÌÌ8Ù{a¤*ÿiª¨”Ç 9îe|{(¢„GIIàßð<ÙgåœÎse†—ùyúÚe¾nm—^®~$ñÃÛ«¯×WôÝÙG¼IôÁʺRB¾ÙYð¬95kŽMÿÇå¿\-“5žܼ‹5çÀsôcòY.jµendstream
+endobj
+722 0 obj
853
endobj
-897 0 obj<</Type/Page/Parent 794 0 R/Contents 898 0 R/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/Fc 12 0 R>>>>/Annots 77 0 R>>endobj
-898 0 obj<</Length 899 0 R/Filter/FlateDecode>>stream
-x•WËrÛF¼ë+æà]%‚øöM~(q"ɲI—‘K`I®`a,@Iþúô샤(:‰KR‰Äcw¦§§{öûYL}üÄ4Ih0¦´8{½8ë]Î(éÓb…;ãÉ”õ£~WÒΛ¨YÓ$¢ÛZ•*×4o«J× ©’æ¢X
-J¢$zx¹øfWŠ‡n¥î Ž¬Õ™DqDï˦ÖY›6J—îÉ!ű2™ðs¯åZ•%op¯š 5iîS-s)Œ<÷»·½!ûH)µ•ôE•™¾7t³ *ÄYÈt#Je
-Cª¨rYȲ‘ïÞ§n<pÑm• ºžw?ݾ¡»ŽŠdd—ß~øp5ŸS)
-™Q¥*y÷2"` ·J·†¶²6HÅ^‘K—ù#ùàðΕ(¯E¹‹æhÛT义üÅd´¬³@Ê"˃$rZµ¥ÅKäªyÄBz«2,¼|t‰Ë{ììÃôÛ¢$iÞfÒ¼â•QànX:Ôl¥kPe®EÆP[°P߬Š5ÑJåÒP£w€ÎF½Ù´w³è%̈4W
-•ÖÚèU¥ºè=…} 1± ]K´
-SZ Užïr<vƒ4bBaé£ts É!H´å”Ç—1{Š<^F%Ùõên¤çuÚt)ÇoàÊàÌFÀŒk’µTÏ­FÆ‚Ùþ. ’•2avSE¦A|fOé„Q+Q>Ò½€ñjD¤mƒ“ïg™ÁÊùùHìn•«ÈªBbDðþí­4¼Ô/«<×÷ Óõœþ|u•æµ@ *×öÊFæ©=êÖî•I”oY$CꇾýÊ‹ÍØ{u‡~×÷Hê¨j>kÜb7š>£"Äsœ¬…K˜Ã‡›ð"Îiá Þ0D˜-í7ï {ó³F óë]†é GvÚ;®÷SßtGfà¯öþ^ö<F¦÷1žÎzq¯?Š.æ·û˜¼ûÃÀJF œ
-Ÿñ‡j­Â<¦Ø$žùØÃ.«ûJ­ÛÚ*+oÒ»yLãY‚œ»ÉŒ½á/Ëß_ik"r_dýâëé°0”pX1@ aÅ3è%â²É¨„âÑ䨓£©“ˆZÂ9a»<=BSÁ4À†ÙéÆÛ}`¡Ïø:eC™­Â=ïnßœ/l³*èDZKÁêö´óBë±V³®ú×ìú6 Ì;&¡SÃ}§l†Á:ØEŽF4p LýûÅö18)õÓ²x"ëÚÑ\8cæÁ²ÔD•0æ¢Î4>­íòØ6¼Š†ùùÙüŽf’Ðâs«±ÁÈvG?ópk"–bœ<*Qj>a¹R8.¡¾ölÔ PøYNŸŸ :,KËc鵚j}¬Âê®Ü°wh=ž6•LÕÊ$¢ö(Ãêê7sG ¤Se«êepÊvÉ„ýÕè—²r) è°Àºƒðq>½Ëä
-€‚¹à*–¬±„7¢ºÏÉêôÖÊmP)nzÛqãgÛÌ«Á‰;ûÖ,¼f¸FõºÖ»œú¢ñûpðýµ#ôç~ ûñì_úÉÆendstream
-endobj
-899 0 obj
-1753
-endobj
-900 0 obj<</Type/Page/Parent 794 0 R/Contents 901 0 R/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>>>>/Annots 89 0 R>>endobj
-901 0 obj<</Length 902 0 R/Filter/FlateDecode>>stream
-xXÛŽÛF}Ÿ¯¨##Hê#ÀÚÎÎÂv6™Y,™<´È–D›d+Ýä(úû=UݼH#g7<ÓÓ·ªÓ§ªNñ›ˆ¦ø?¢eLÉ‚ÒòæÃÓÍߟn¦“ÕŠúìƒ)%Ód² Ùj‰ß£Õl²"«iË[0‹sº°þþaFQDO[Ši±šÓS&óSzJGO{í4”U¥®µuw”WiÑdyµ£·O_oîâ°wt°y…%”Ùü?¶y¡ýŠöôQÎ)سÑ|L¦V§¹ªuFªÊÈíMSdT™š°‚/[«#6ý×Ü$ëédM‹%\§’fÉr² £‚ÙQ8³Œ09t§q¸$¯¨ÒGüpµ*
+723 0 obj<</Type/Page/Parent 635 0 R/Contents 724 0 R/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/Fc 12 0 R>>>>/Annots 72 0 R>>endobj
+724 0 obj<</Length 725 0 R/Filter/FlateDecode>>stream
+x•WËvÚHÝû+j‘9Ç$0†ìœ‡g2c;N '‹qÔ@g$µ¢–ÀÎ×Ï­~ð2™™ÛÇ GwÕ­[÷V?‹©Ÿ˜.Œ(-Î^ÏÎz×Jú4[àÎèrL³ŒúQ¿+içÍJT¬iÑ}­ÊF•Kš¶U¥ë†TISQÌ%Q=¾œ}³+ÅC·RwG Öꌢ8¢÷eSë¬M¥K÷äâØ?™\òs¯åR•%o°QÍŠš•´ ÷©–¹FžûÝŒÛÞ}¤ZKú¢ÊLo Ýͨ
+q2]‰R™Â*ª\²ldÆ»÷©\tk%ˆn§ÝO÷oè¡£"Ùe§÷>ÜL§TŠBfT©J>¼Œȵҭ¡µ¬ R1¤äãÒeþD>8¼s#Ê[Qn£9Ú6yn"1E
+Ü K‡š-tM
+ w-IvíðЩå» [»ÃUë%uVMS½êõ@8¦¡‰ŒnëTö¥ŒJÎ.û‰ßbr€1ôgHžª.Ãà›ÂÓÚFÂÅ&Ë:p4]‘04mDݼÕé=G*ëszW¶ÅznÏ9É&"pþ¡3•¨ÖõXÆà ø:PL@7šD±ÿ¶ƒn8æRï+Éíôí¨—¶Ü†hZH4ÿba²2*TZk£M”ê¢wû@bbº–h|,Ü؃á€8 ’ŸuâÕý{ðçøÜŸ?˜D#¦ù~k1IÓTCo4+^N7Ê _@Ó77؆‘-8¤çßdŠ{'¶þ_íÃT×kBh~† ,þ½•­$ô§ªÚÜ(jÝ.²¶F²tA líYn2ш9tÖX,M…z¦–ßôœ>ü¿¶›ŒÑPÝ€Ül%Q°¨8—²$£ .äѤº\´,±$æºmh³[ šÈB*¤€öB}p]¢Ä@³¦RÓð‹ðŒï­ª­äs:–5;å (9Õ³z7ÅUilHy[/ë+m¬Õé:sඋp[-j]le*H$çŠæíòhgù>`ƒïì# …ž,D¶ïd‡’R
+:‘ÖR°ºv^h=ÖjÖUÿš]߆rË$tj¸ï”Í0X{»Èш®©·Ø.'¥~Z6
+endobj
+725 0 obj
+1754
+endobj
+726 0 obj<</Type/Page/Parent 635 0 R/Contents 727 0 R/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>>>>/Annots 84 0 R>>endobj
+727 0 obj<</Length 728 0 R/Filter/FlateDecode>>stream
+xXÛŽÛF}Ÿ¯¨##Hê#ÀÚÎÎÂv6™Y,™<´È–D›d+Ýä(úû=UݼH#g7<ÓÓ·ªS§ªN󛈦ø?¢eLÉ‚ÒòæÃÓÍߟn¦“ÕŠúìƒ)%Ód² Ùj‰ß£Õl²"«iË[0‹sº°þþaFQDO[Ši±šÓS&óSzJGO{í4”U¥®µuw”WiÑdyµ£·O_oîâ°wt°y…%”Ùü?¶y¡ýŠöôQÎ)سÑ|L¦V§¹ªuFªÊÈíMSdT™š°‚/[«#6ý×Ü$ëédM‹%\§’fÉr² £‚ÙQ8³Œ09t§q¸$¯¨ÒGüpµ*
Uç¦r¢c©40+¯¶Æ–òw2ÕûÜQºWÕNßLÓZhõ~Ö+´€;‡vÀªÅª³1XÕ#/Ž
-FÙñ“óx2ÚÌæ` x¼ñÔ¹6ÓB0¿Š”¹YÔýLŒÓ[âÝ?¬)š1Ípcv h¶œÄ“hB­†ÇàÄoB¦7¿³Ù==§4Ž—ìÛ§ŠŒÍ<ø®9Œ­åšCa”pÓlé‚BHð—°l\±Å¿©©¶ù®‘JVàq™šøžuf|¸½ÅQ!+
-säwn“ÄÀ9åóЦ¦±Aç À¨©ˆ^TÑh<¨kÒ=)G·Uïo%±(»Ék«
-©ZL¹½²ñlýH f‡¥q„4‡aza8?6Þ7ÎÞ&UŽã`¸'_³v‡ç¬É|öÓUw6d׌Ôw—€e’6ÜüÞ!ïðšUÊL,]Üvi
-¡ê |^^î`$™õ½êj]PæªàúrÂõ(-9GxFẟü©MU[è$܉;ú|P˜÷$¾éè}äw8‚u¦€f Ð{„ôÂpqwUiÎ6PIxõŸ{µ…ëýæ%Š®^rk* ‰ã^Û®loXOe=}d ˜á_¥Ø‹Ø2 kO°jÃCÔáuºK…"ÕtÚ ˜ž¼Ù!ú’˜Ór”ð…%%hVÐHÈ(D3h%³‹´×‘ZÑztà
-ͺotûÇ=âV2C÷‘ÕË¿À²ÆÛiDó’[L³ÛOh<þªA+6r<LŸÚÊo®¾×)1IÛI|h;"¾Š}ð-Ãq€–MQ稺´È‘(šA aÓ=”`ZÃQþRRûF3´>®Ùd¨-im,ÔºDE œÄÉ›ß%‡ Ý(9zšñ¢26'^Ò
-òMÄŵÁ¤oZ “À|ÓÅÁº=¤Hû>á¼6ó~ÑBuöýZk5Ò¡…jØh7òàÝÒ3KÅ3‡ȃs·`Òþ*T¹h±DT,PV¤÷||ÿùÃ{ú§5_ý>aȧyf¿|¼ŒùÂè¯>Ì–üåK–%sÞ‹ øåæ¿:Š¦endstream
-endobj
-902 0 obj
-2101
-endobj
-903 0 obj<</Type/Page/Parent 794 0 R/Contents 904 0 R/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>>>>/Annots 92 0 R>>endobj
-904 0 obj<</Length 905 0 R/Filter/FlateDecode>>stream
+FÙñ“óx2ÚÌæ` x¼ñÔ¹6ÓB0¿Š”¹YÔýLŒÓ[âÝ?¬)š1Ípcv h¶˜Ä“hB­†ÇàÄoB¦7¿³Ù==§4Ž—ìÛ§ŠŒÍ<ø®9Œ­%Í¡0J¸i¶tÁG!$øË,Wclñojªm¾k`¤’.S³߳Π··Ø"+d ÷ôð›ÀlÎpfæiö¨Êºu`£R…#gH,åó ë‘)'ÊKö@U5=û,zÃSÌ*§íKžJ ®oNDÿΫÌ}yòÞÊzd)“ò`ÍKžáˆ€8ý
+l®±ç·­‡ñL
+tÕ4vP× s µ ÂÁÁ·¼nYˆúdHÿ 7®ž\þêô` -oîøb>õj+Öh\ñr…l*i¾žÌà ´Ìaˆ—kɹ3…Ò6ßÁÖ’VóîÐï¶Þ^½.ïH:Õ$ÝóL:8ˤ03Ø\ßP‘è@“»ø‹&*ô‹.x¥‰æ^aÒ_„?kÇí¢ooÍ!CE
+ÐEñ*'^ÌÑâKŠ– vQF­‹¢—"7{€˜…Ž¼’oµ/ÆíɃ³JŠ§Ñ$œ<c6F³Ìž‰ÊVÕ´¦^ZÓvŽçÑüù-!*4‹Ï…WðŽ¤_em¾¶MÄûåZ³û“•hÃ(Z1¥dÔ㔬/´!7u«ÿhr«Y2ÉÕ-:ƒ€{Â*©?o8ÆìlÆ1ênŽ1 ŽÙnö*v÷ó ªƒ—¦úJy^*_ק͈5¶®2ô
+fð„°éJ0­á()©ýC3<}\³ÉÐ[ÒÚX¨uÉŠ8É“7¿K Ás äxÓ¤ÈíP±¹ð’Vø“D\\@ ñVá 4°c
+˜tAq°îÅ›R¤O8¯­¼_ôŸPý{­µåÐB5l4‹ xg·¼™¥cŠ™C$àÇÜíX‡²¿
+].Z,‘ ´y{>¾ÿüá=ýÓš¯
+Ÿ0äSˆ„Ù//cþ†0ú«O³%ù’eÉ”÷" ~¹ù/)¹¦endstream
+endobj
+728 0 obj
+2102
+endobj
+729 0 obj<</Type/Page/Parent 635 0 R/Contents 730 0 R/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>>>>/Annots 87 0 R>>endobj
+730 0 obj<</Length 731 0 R/Filter/FlateDecode>>stream
xWmoâFþž_1E•Ž“ó 퇊¼õÂ÷R5UµØ ìÅör^;U|ŸÙµ 8½HmPx±wwfžyæ™ñד5ñjQ¿MùÑÉåüäf~ÒôÚ¿%+ühR¯ÓÆ{wÐçï=¼%’–¼7qLù†åÛ&]Ð|‰£{8jØÛMšûõß7‰ŠÓÿ8ã¿·ó/'M:kÁÕ)ÿûûìS§ýyÐ+~ãógª}Rq ·†Æsú6èÕ¾¿w4î6¶î½8o\ ^ÙÚiï&ï†åîc³Ãp³?O^=á~4™•‡ãÓn³Ù|u÷drµß\Ù=Ñ[™L®ìþÆí9µZãNßëÒY{àµÄá|~3žÆ?MoÞMo®ir3½Íf¸:cÜlŽ’6ý•ÓHç^/Ïqë"Ç3Îq㶛›kÓy¿ƒ‡IŤ“@&”jò³$‘qîH Šå–‚D=»»;ÑLD AkmÒS"KÒKJ·Ø©ã@¥Jdž¢Ì¤X”&™ü‰}AÏÚ=k¸>_K¾¯³8¥ÌH¬²»cé§ü5Åí½ÊOÏØD™
Ø^“ëÊ“®$Z§Åio‰m5ný<Ú³>¨ âõÇv¯oo×bÚ¼N¯……ç(‘EÔmu£ûVìðºŽeü¾,þOD Ž'’ÑÐ2„ˆ:Oî¡}xsÞE&¼ÙW« À–l;¹¥ê¢-\˜B^#³¥ý)ö›=¥ IBeR¯
g§Óòú@÷Ür$.Óü°'²ÄÈSøÁFº‹Ü[š˜T…!m´1Ò¾Å`Óo©Bi08&[*Á :Q¸º±éš
EòlHP£Ž+¤©Ì±M× >ÌZ$Ø72ÒÒíM"H‡»7´ØQ —" S{ÜW,Hy¡uƒRL[­ØRT$¶W…þ!ö%q鬙Ä>ì1
-S"¿fˆ)(£€SɳÂrH•1ÚWvõqô§dT´A‘†z׋¦Ÿ‡¬gFÅ+èÊå±®“<µmê?JzìóZG]9[&:Â1jÞõšöù¡‚nxDSm,¡ ÉSÅ›±T«õ¤XkÔ :T»ßQ¾–&¡@ök6öE‚f…% Ô^Øž¡öK<]´§«±xV+¬)Ä¥6á&&ãy^ &BhŸG¿!Af­3¨–‘œ
+S"¿fˆ)(£€SɳÂrH•1ÚWvõqô§dT´A‘†z׋¦Ÿ‡¬gFÅ+èÊå±®“<µmê?JzìóZG]9[&:Â1jÞõšöù¡‚nxDSm,¡ ÉSÅ›±T«õ¤XkÔ :T»ßQ¾–&¡@ök6öE‚f…% Ô^Øž¡öK<]´§«±xV+¬)Ä¥6á&&ãy^ &BhŸG¿!Af­3¨–‘œ
>
vQõr¬Óø&ÓÑx~3¥ëéè#>†‡£»áåÝ Ý>Liþndû(Ï.¹Zäëñ©{tÚ$„
2¶±ùk¯líÂ)¸»#“‚P+{! õÖ‚…Ɔ N×™¢! ¡hy"P?‰„ùPb<o´1cäÕd<¦©Œ66‰°÷¬ÐŽÙ¶IôF&) "—Š(1ß®•¿F:˜œŒœSµÁ"ë6…Gèão-É$ÁÁTY¬\+oÜP3òž~-­lASÙWC¾ˆc4f4¹@™M(v2@‚™h9¬¿ŠÙH_-P-øy¯ŠM
Ý–Á©Ug,Ô:”IÅç¬û‹×Ú*ïV`Ö
-“ar[Ykn’('*K¶ãYØyåP¡Ñ\Šb (ÒZîò€þźÉüu%¨ ¯î06îA¥ÒÝháTÆÅB{á<-Á6?Ôvñu¡Jæv§u °}Ô½±ã bg¹cMÖa;%q:´k8yÆ’ìEòºäM¿ìWV!yd±±m›%ÊM†¢òõH<qI±„Ú^jÝÄ2תlÓd·™ç<BV€+ñ"»ãqœØ²iþOñ,…~Vº³Dnqn^E |4?™»Çƺ‰Fꥻ\ÎíøÆí _Öêõ=~ŠçG4úÙðþrˆ&¤¿p©^k?ã<€é®¹ågý¶}fú¯“E·ß… Ø­û…¹æýÉ?wTendstream
+“ar[Ykn’('*K¶ãYØyåP¡Ñ\Šb (ÒZîò€þźÉüu%¨ ¯î06îA¥ÒÝháTÆÅB{á<-Á6?Ôvñu¡Jæv§u °}Ô½±ã bg¹cMÖa;%q:´k8yÆ’ìEòºäM¿ìWV!yd±±m›%ÊM†¢òõH<qI±„Ú^jÝÄ2תlÓd·™ç<BV€+ñ"»ãqœØ²iþOñ,…~Vº³Dnqn^E |4?™»Çƺ‰Fꥻ\ÎíøÆí _Öêõ=~ŠçG4úÙðþrˆ&¤¿p©^k?ã<€é®¹ågý¶}fú¯“E·ß… Ø­û…¹æýÉ?n<üendstream
endobj
-905 0 obj
+731 0 obj
1856
endobj
-906 0 obj<</Type/Page/Parent 794 0 R/Contents 907 0 R/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>>>>/Annots 101 0 R>>endobj
-907 0 obj<</Length 908 0 R/Filter/FlateDecode>>stream
-xµXaoÛ6ýž_q6ÌbE’Û ÐΚ¶Ú$‹Ýv€ÝŒDÙj%Q#å8Ù¯ß;J´e#Z MQ#2)Þ»»wïŽùç ÿ†ÔP”œO.¦¾7ÑöC/ðàS8ð½>õGÃÍïZR¯`çl>°ÿøuŸ‚€¦ ŽŒ†4íºOÓ¨3.Tµ”šÒ¢’Zš*-dÒX¾—”ª–¢¢Oi«µ¡«)EY*‹ÊP¬x ­ŒÄI“÷çTj{
-™¥ÐòˆîViaODñbúåÀ§nÐóB
-oe$Ú"¸O3¹À
-yHk™eݯ…Z´ÐjUzlÓ’©î ¼£hârüú”‚~C?ôF;„z¡×óh²*K¥+@Ë„^ @«ü4A ·­wmfuCfVçº`Ú˜ÓÌá
-NÒlŽŸ›ë7×óù²ìZ\OnŽ¥‰tZVè2g³zÿþ{GW×ôêöòãÅ-?Ž/ßÏß]Ðëë[š¾½œÐÍíåÕôâöèÉÓ¹´¡Ìg3·êxñMQÏ÷Jâ÷º¬lålõÃùGóùáóÌÄâÏÈÊdq¿OVf`¢ ´›º²éyPí&ž(üf{¦ÉB³w$Ÿ[lߣq³t]É55gè>V[
-€NÅ}¢Õž?º©ã¨iž*I¤FÃÍ2צëa ãšLRž=ÒÂfƒå¯ ;&¿ó"U$»F:¼Ó›çy‡Å¥†üŽ3£ ¹èV~÷Ç;«¾õf×Í[.±ëÎg4å¹ï¦ÀÐÈ:÷æu
- ܆µ\HSjb2Z¯§h”x ³Ú7Œ±pþMÀN ­ªŒV˜âÐL®KY4N]<Ì;\rxÚ<³Üpâ<-à†W —îîäêÄy'õ¤gÛaø¨#ºÀÚò&{Ü^tç/¼f{ÔlïÁ#7ÏÃÁЮcÎÀ‡\…}|æ48Ý<pGo=æ˜}ÂÅö3VOúlÀžÃ¯¶Ÿ1Hø˜Z«ígeú˜Ê¶ï¶Ÿ±ÚclÛÕ;ÈvÌpqAƒðd§ l’§xÃÚuMŠ—ô(ë1ïGŒy‡™ÚLàÏ„·¸³×QíötˆœúûošI©]o§#Û˜··¦K ‚…À<ã颡œ» 1÷ÈÞmç|¬Š¦f¡?L¾)¯Ø0äv°mowO„·vk1›wÑe.6wlæYµ?@~íï÷>ê¡hëó7|ù
-·´¥¸G\6²s/²*·5¾7©…9.Tê+Ùͦ-ÇŒ”ÓéÊ¡âGóh*™S]ru59 k籬¢cûf$ʽšã%¬c'%¸æÔ<¦Ø}M¤gE1Ù^m€m'GŸ–¸äÔ·SÌ$H´Ê…z|>‚„YW¸Õo©no˸Ô`³7j+ªG "7›³JÛ yKËN­‘NØØdí°+´"Éß´Âãb
-ÙÜLïí9Z–‚oÒMÜwCýl·`BWHP‰é^Q¦"Ž0c*ÐÞœYë*X€•M)ÿ
-endobj
-908 0 obj
+732 0 obj<</Type/Page/Parent 635 0 R/Contents 733 0 R/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>>>>/Annots 96 0 R>>endobj
+733 0 obj<</Length 734 0 R/Filter/FlateDecode>>stream
+xµXïoÛ6ýž¿âl˜ ÄŠ$;¶ œ5m3´I»í
+³gÐÒE!cº{l”=wgÑ"½·à%Þp4ÛçqØðáŽԪ‡´–YÖýZ¨uA ­V¥Ç6-ipÕ½7pMAŽ_ŸRÐoèà‡Þh‡/ôzMVe©th™Ð h•ß&tã¶õ®Í¬nÈÌê\L³bZ€9`¡S# ŠWð¨],ïe¦ÊL¢K$<ù ü°´ãKA°à³i°ÄÑÑ`޺Ȕˆ÷ã›(MïÿféàPâv>XÂpàZTß|b3FårÍ8I¬¿®…®í‰Gç,5ö_&”+þà„¥Tâ&ÏN¶Û7Á`ètÒ!3s
+ƒ‘7lFMljbxŠÉv6@$ÙP›‘’98e>²`š‹mŸ
+ƒ®¸¶È6Úãœz¿ÁãltÁ‚¶âpÒˆƒƒ¿P—Q-ˆ¬‘Us ‘ÊsQÄ–ã›C­ìì(N‡ûtǾ5—)+ëOs ’BE©¨¤=©[cبÄ:­–¨“©D–á„z[“s‰Ê2µfRá*åƒÈËÌ2i©Ö°ï
+ò ²o‰ ]ÊøŒ1¿öé”s  nxbï¤ó ñLgã/•j¡¨û´RÕ¯FFØ»JdC ÄÚ
+\Sj¢3Z¯§(”Ø…Þ åƒ ÚX8‡"`»†ÖªŒVèâPL®KY4N]<Ì;œrØ
+mž¿€Y.8qžð Í+ŽKw·su ⼓zÒ³åÐ|Ô ]`mú“=n/ºó^³<j–w‡à‘ëŽçá`hçÑg ‹Ã]…}|æ48Ý ¸¢·†9zŸpg²=ÆìIŸ Øsxk{ŒFÂG?Кm¹•é£+Ûîm1ÛclÛÙ7ȶÍpqÁ áÉNBØKFœâ k×5)^Ò£¬Û¼ÿm1æfjÓ?Z¼vâÎN\G}”ÛÓ!>rêì¿4R;ßNG¶0o_M—h5yÆÝEC9÷bï3½Ûöù˜MÎB˜|;]^ °¡Éí`Û¾îžoíÖ>b6ï¢Ë\lÞX̽j’Dö÷Æ{ŸFuS´õù›¾|…WÚRÜ#.Ù¹Ù
+™‚׿›ÔB‹*õ•ìbÓ–cFÊ×éÒ¡â¡y4•Ì©N¹:›œ„µ’óXVѱ݉r/ç8EE ë˜GÃI žy9.v_éYQL¶OE[`ÛÉѧ%9õë”3 ­rD¡nŸ aÖ.õ[ªÛ×25èÄì‹ÚŠêQƒÈõæ¬Ò¶CÞÒ²Sk¤66Y;ì­ƒHò7­ð¸˜B67Ý{ûD…–¥à—t÷ÝP?[-˜Ð.¨Dw¯(SG˜1(oάu,À‹Ê^)ÿ
+endobj
+734 0 obj
1839
endobj
-909 0 obj<</Type/Page/Parent 794 0 R/Contents 910 0 R/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>>>>/Annots 110 0 R>>endobj
-910 0 obj<</Length 911 0 R/Filter/FlateDecode>>stream
-x¥WMsÛ6½ûWìø¤ÌØ´(Ñ”•KÇùpë™ÄueÒC. IHHB@Ûʯï[€ h%v;ÓIb‡Âî¾÷öíêûQJcüIi6¡iNE}ôjqtv•QšÒb…'ùÅŒ%“ñxL‹bdª*j´£R®T#Ë Ic´!½¢ãË¢ÖÒÙ(Y“²d¤k ^$§Ém$•’Kˆn´“¸#œ¿ýbñ']à‰²¤­Q“†é4&ä2Ú½6¢ˆ™Ž8”|EëªmJiB4çæƒë¦‘…ÅJsâ Á ¤,Œªv$ÈhÔ&ŠB·H’c¼]qõJù~?JÓY2¥<Ë“ŒjJóirÞ]Uô‘1rÙ ‡Ø-6ÒHÎSP¡ëm%k
-Ý+·!)ŠM„:mVB)¦$âÄ7–-RÆÖÕ»ÛEúòÄc¶éë?ßã&]]¿{‹_Ò€‚ºÜëÖBb•ÕdÛ­ÛI³[¯T¾7H® i!Å
-À®e#¡D_K{rV…C¹Óy?ëMY:9°vLƒ„‚®kß–¢•ŽOÞ£ÞÛÒ£W^…%9ÎþN•>ÝO7׋äNT]×@ÅÔ·ÎÍ‚.1!c'V?„)¡ñ+(& '»ª&Óƒd:K½*¦ |Þ]õ¼Lg“¨†Å-œbÕA÷®x¬†9ÞWz/—d{¨{B1#Ú8·}yv¦:t«[SH„Xˤ‘îŒSÝOÙ8q° [%üFùþ­½Ç–ºhÙR|–„ž/ª¶„4¼‰3Z1zˆÃQ µl¹ªèë
+735 0 obj<</Type/Page/Parent 635 0 R/Contents 736 0 R/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>>>>/Annots 105 0 R>>endobj
+736 0 obj<</Length 737 0 R/Filter/FlateDecode>>stream
+x¥WMsÛ6½ûWìø¤ÌØ´(Ê”•KÇùpë™ÄueÒC. IHHB@Ûʯï[€ h%v;ÓIb‡Âî¾÷öíêûQJcüIi6¡,§¢>zµ8:»šRšÒb…'ùÅŒ%“ñxL‹bdª*j´£R®T#Ë Ic´!½¢ãË¢ÖÒÙ(Y“²d¤k ^$§Ém$•’Kˆn´“¸#œ¿ýbñ']à‰²¤­Q“†é4Í’ rm^Q‡ÄLGJ>È¢uÕ6¥4!šÆ ŽsóÁuÓÈ¿b¥9ñ…àRFU;d4jE¡[$É1Þ.Ž¸z¥ü¿¿¥é,É(ŸæÉ”jJó,9ï®*úÈ¹é ‡Ø-6ÒHÎSP¡ëm%k
+qâË)ãëêÝí"}yâ1Û‹ôõŸïq“®®ß½Å/é
+@A]îuk!±Êj²íÖ‡í¤YÈ­W*ß$W†´b€½Úqÿ‰¶r'¤›jw]7{Nù0]Ôè‹ã
+lâ€)ãvi{gùöY<WÔ” +(¾Ã¾Ñø”I‚Sè‰DïáïýFr©•^«BT¿*€S÷¨uç\5 VhY/~D8!* Ò¢¤¥¨DSp? 7VBU¤¡1/ûAi×+Úépz@ #ØßÁÙK½•Õµdø­nN<PgW0loÏ#[/“B7+®>•Íæ
âÒK'08—îÕdüæ­
-½¿Ì(ô7€8 Äuæ—uDÙö †}–Ò9ï‚ÏK’Òü'INzñþó&P{ÛQû„B  ç¿!@”=KOðÂB^Ê`žG[è­äs<Èc÷Ó—QïK‘éÄ=xçÀæ÷­Þ"öÑmgð
-ª5¯ê{‘yønÈnü:ÅC';“o?`|ýCm·<´„ÁšPÁ¡áZª‰MOX©JZ,O"ÂÛ×7WÔÝbÑð·öžÊߤFJ6»%6RÀ%5TßÐæ~3xÖ€òó_}8ÖÂæü ¿=*áMF£ßKáÄ’'I÷Ìo?T‹Oõï­„Û–t§°…: K¡?‹[ªe±²56Ez‹åü
-endobj
-911 0 obj
-1731
-endobj
-912 0 obj<</Type/Page/Parent 794 0 R/Contents 913 0 R/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>>>>>>endobj
-913 0 obj<</Length 914 0 R/Filter/FlateDecode>>stream
-xWÙn7}÷W\äIA#Y›µä¥pœ817n­"}Ð 5CIŒGä„äHŠþ{Ï%9ZÆ
-Ô6dÉÞåœsÿ¸èQß=÷i0¢lsñnvñavÑíL&t|±+|èÒ 7íôi8ã}¯Ëï­¤%_Á)ì^ðüåíz=š-a~4Ó,ç]še-å(W+åEQìÉ©•–9ÑV ú¨«‡´[«lM™Ð´T9zC[iÕrO~-<•"{+I¹Ù鈜¯Ã¦È|Lúµ$£åëÙ÷‹.µ{:Ë[V.¥µxVi˜‘t·)­Ò±/ÂÉÑgC|ñòv”âo‘6>þ©N©…Ä3³ÙH;CL~‹Nf•U~OÙZfOÄñçʉE!ó[ÈÑ
-þ];gLêJ&æ#%€Ê­‚[‡rF•lŒoõ£Ø,D¸õMiXA.¿Í¢çr@CC`Heµ£X
-tÇyËUei¬a
-«L…¹uÐRjýÂ%å
-Žá VšÒ¡“s5'ÎØyN¯®K<Ûðû}Ñ~ÀD#¹»C¡þEÛ«^gòŠÎ*xz…á_¨C´b®~žr Ô^òí=7ù*9=Ð0Ãʵ»6;¦Ž;€Å2‘2Žvq.¶’7à‰zG2±¦@ãé:__°œ#™*ŠF®¿Ü,pFà…i©qCƒJÅoƒÎâÄ›+Q˜j;ÑÕÄ"€…¦–R CÍá4\ÿ¨–˜'
-žO]±p¸=ZÛѯаQÈ"­'s½†ïÓç/÷óùc¸0ŸßTØ ´¿1Ú[S<J?Å÷óyÈi>ÿ ·ÊÍRmŒÊ“Ì€ÁýVb:|N°ÅNì/~QÍ€+‘„„g¼ká BñϯZ ì3ÙGà¢`/Îá“»gB{5¼•°ˆ¤àÿ“Ù!tû†âôÉ "ÅŽµ¦|¤p"a"jÞRC¨op‹šbYòÆ»7gX;&
-Z-ƒ~‘1û"Q°øöQªidÊü×Ô8¹||L´2ydT¨ –ð°Dâª"Eš4‹(M&©¿¦"­à<+Cˆ ÆóÜïÐÃ
-:ãSpzu94Ômàè˜8ª§4ס²ÎŸ.Òî /íÑ“4Œ{£q‡ÿ¹áííøÿÇãõý»k®½ïdôÞds€`øÚñV;^ký÷Þ=ë q0e Øó¿ø¹Ê5“endstream
-endobj
-914 0 obj
-1526
-endobj
-915 0 obj<</Type/Page/Parent 794 0 R/Contents 916 0 R/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>>>>/Annots 113 0 R>>endobj
-916 0 obj<</Length 917 0 R/Filter/FlateDecode>>stream
-x­WMoÛ8½çWÌÞ –-ÙñGo ºéöÐEwc  Z¢-¶’¨%é8ù÷û†mEIEP}‘œyïÍ›ñ¿W)Mñ/¥eF³åõÕÝæjr¿¦tN›=Þ,V¸(hšL§SÚä£e2OèzóýjôUŒpJ7ä4í®éAÔ;AY2MžùY–dÉ3:¹ŸSš†ýÆÙû>«'‰…¥pÔÕ8i¨0xf¨8ÈZ6ŽJa)/EsmG'I¥n%©º5úIÛkR ñ)„[ÃûhCFVRXi?Pãã¦4NgøGûPECòYY§šYéŽm0åxC{]Uú„ØWTÔ
-WÚ„þF’ÀŸ+%µÚZµ«$Ù\6G[¬2t9õ# HÇÙ"aG_öô¢Thj´£BZÕmÕÈ=ª¦Ð'Kn(
-ñddu{è781$v“®ÁÉ?ï¤í´®BH¢²ES DÎÉìDþã$ $–ëÂW;U)÷¼ ð±
-±šë‘«‘³iä³C¿ã»b»É )”ÅÏĶXôŠF5Ö0 嬵ˆ$ÁPf¦3£R[H»Ð< Œ:øÙ^³€”—YOeª
-u𵡗wkd. ÙäPèá<]i$Ô^&Ÿ·½ðÒtÔ¡ÑƘjòêXà»!³~},¯9¸*3H}U£ÑM~ÛlôÖXß÷Âîç:éÔòÓ2¿ï—`~4†íZ7Õ Y]¹) Ä¢¼em(ÕH"Åí·G.µÈ0#‹§¡¼ìlПyÁc?vjàks£ZÅÔP^!ÇsY ÄóJ!ØðüâLêà[Óæï~‹ó@<J_Ћ
-®‡ÚôJuËþ2¥³¨£žÎ"Šéz–Ìh¼ðå{›—îØ~{“ª? ©âš§)zï|µÄuºÆ%:ŸÏóÒ`0~¬nPñ—ä6
-endobj
-917 0 obj
-1405
+½¿Ì(ô7€xˆëÌ/눲íA û,¥sÞŸ—$/¤ùO’œ$ô:âýçM ö¶£ö ….@<ÎC€({–žà……¼”; À<¶Ð[É-æxÇî§/£Þ—"Ó‰{ðÎ;€Íï[½Eì=¢Û0ÎàTk^Õ÷"ÿò†qÝÝøuŠ‡N v 'ß~ À øú‡Únyh ƒ5¡‚CõT›0ž°R•´Xž$D„·¯o®¨»Å¢áo ì=•¿I”lvKl¤€5Jj¨¾¡Íýfð¬åç¿ ûp¬…Íù~{T›ŒF¿;–‰%O’î™ß~¨;žêß[ ·-éNa u(–B,·TËb#eklŠôËùºQ>þ‹[“G¤¶Áð
endobj
-918 0 obj<</Type/Page/Parent 794 0 R/Contents 919 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-919 0 obj<</Length 920 0 R/Filter/FlateDecode>>stream
-x¥W]oÛ6}ϯ¸,bù#nâî X»ëð õЇv”DÙL(R!);ú÷;—”[mÚaKEyï=<÷ò\êádJüNézF—WTÔ'¯—'o—'“l± §‹[áaB³ù«lFóÅ5î_¾Ä­“Taî„.çs\ÓÈl–-žFæ“«lÞ\]aR´A˜!ôþ‚ã›W4›Ð²¢«ë-Ë8Ž7Åù›µh‚t´ÈèW™·«•2+ºuÊ„tcs-kÿbywÂ^¦óäet9Êey¾È¦½3ÁÙ²-‚²&ÍœÓtÚÏœ]ó¼åZyŸ ¿¶.P)}áTÃd+ZÛ-‹·@@Í.zãRtÚª°¦÷¢ÎEFÑS2Ï¥?²äØM/¶có½×ÊÙ8Þÿþš
-­¤ Ïìž¼té.ÈX¼^K²¸8ÚŠŽ„³­)3º±.Ž8‰‰^ÂBâ²|u£¥ïÖÊÉ"X×eýôçÔüqAÞRg[ÄIh¢Ñç°(BÇDG·o˜ T‰rž‘r²Øƒ‘²dC@º Lɬ‡µi¹¥…¼VQ„VhÝQ .L÷”¼ÔÕ©@w-Ba"²È‰¬UY¢6„¡\†­”†0²­œ_ "ÿeÔã“ßæ¾óAÖYŸ°$Õ°˜ÆJi\8aü×øg¨ÞNˆù“(c#4FöA [iyšÑp‘ÂSÿ2×"•`ªm˜= f‰ÉÞ®-àD²c1– _kPÞz΀1C¾Î3ŒW)MµuNj¹á ï¦}:ß®U±Žñ±-Z]’¶ö~
-å6¶ƒš ýòÛÝRúÞÇšÞÎ,Ë™µÀŽB)C®Å=K
-Â2
-*>¬Å݉JùÞUûª„Ò‘ëDW­Vë
-endobj
-920 0 obj
-1444
-endobj
-921 0 obj<</Type/Page/Parent 794 0 R/Contents 922 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-922 0 obj<</Length 923 0 R/Filter/FlateDecode>>stream
-xVYoÛF~÷¯˜"Ií
-á@Ÿi“31›0¢AÌÞCµ0붒5è˜ç“ù…^ùgï­T)#º"«ª¦”$ï„¿zضQàõÚR¥Öì”çÁá½bc$$ j©û Â{ë/hèªfhÅ­ /z჋“YéXŸý0\ªú°wŠsØ“ÐVR%6’l
-TNƒ†.½U°,òV=ÁðŒ•™¶îrÁeWüKiŒ6TIkÅZö.Åì 9 ä}D|>9+ p„Ô!í^·†ì½u²z¦ech€ÿÏczžPryùã·= rÀišt,
-Y³š
-n±ý€ l°BíúzçõPºlèEe¢ †£…6Ò `Véó®¦[a”F›ÙëZ!|~ Q2¡1†¥c·Y`IØ_ ’xêgÜþR0ŽèO—+¥\Ó{oùÏ!Âsί}’0¡|POטڞ²¯k#*Þ²Bf¿ »†£•ô½›G^k9€+/ëZýîùæq˜¤wˆK7ß"/ÑCŽ¶Z®áÞ¾ÞGzðÇ^î˜Ð¿XÃZÀÍ.IªÆ”«„CvhetÕÏØ×=v¡ˆüðac‰1¸Òe©·ìs‡N¼<(ƒ »ßrä3"s¾©ï´~ŸÃqÜ烽e¤=žÓýªúßy~ʦv›Œw{écÄÍ»-2žÎ"^™±î-¢×W¿¾¾¢F‘™£7:ó[ž% ®A`ûžµ5ñîÌJÎÒ¤³ï·“ÿ}o~endstream
-endobj
-923 0 obj
-1321
-endobj
-924 0 obj<</Type/Page/Parent 794 0 R/Contents 925 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-925 0 obj<</Length 926 0 R/Filter/FlateDecode>>stream
-x•WïoÚHýž¿b¾‘Jà¡@#õCª6×Tm”k¨î*E:-ö›Ú^g×Aº?þÞÌÚÆÜU§(€íÝùñæÍÛñÃɈ†øÑlLgSŠ³“÷‹“‹“a4ŸÓþíqeã³hJ“ùL~ãÃiZaíÞ̦ÑüÙØÂC8h?`èõå[Mh±‚ßé?y>¤E|:&Ýê²4ùšª‚
-gò2V©< äµ{ÔοZÜŸ¼¾œÐh, Æ3X:ýa+ÊÔŽr­*-V—lÇÛL·Æ<­¬£­ݪl©Èï|©3^^yÑUIÆ“/Í×é9Æ6Ëtž°Å*y'{Ò`tÙ+¶á°P±IMi´‡3ûhxËr'$ò…µ©vÈ*]ay›'kr˜©ÒØ<ª=§#uvú¡2Û´[GªÍ\¯’| µÜ5M´Ø ÑãÎ3Ú(A¸“£ä'aì‡ô–¡Ñ`ü&G”«Lÿ­R£ü(|£(:·§òîQ¥•>ÇÃÚ ØÂ4
-ÿÒwúIeXêÙnK¶•Áad‡ë/ô.Ñ=׳Æ)€ÇaÐèˆät_ã²m¿Â²Ñá6î©P”ã |ÝÑ ‹ xu`¥_›hЯ¡—Ú˜Î^2yî7ç@™5`pŸñ8{G¥ö"p$W¼¦¹s(¤ðy¦°ñk“/š{Ì¡[÷x7r¢»Ë›®lÁyZ‡²øR¹R'`ÙÕŠuZû‡6[£¾ ê¿és&‡j’\íÄÊÆ•å.C¿?ã…¸ñ%
-Üzi•ÛnËŒÇðz\I?|¹ùÖªHè
-ë”38|iqž4Y°E40ÂbòÆñ¨%†ñ¾Zf¦„
-ô­‘åŽ|óq¶éÓOK1'\šB«%Æ0OEâ’©Éõæü¾__ýI=nÙU%^
-endobj
-926 0 obj
-1583
-endobj
-927 0 obj<</Type/Page/Parent 794 0 R/Contents 928 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-928 0 obj<</Length 929 0 R/Filter/FlateDecode>>stream
-x…WmOÛHþίµ:A%pâ$„À7ZéNê˵9NB'-ö&ÙbïºÞ54?þž™µãÒ$¼Þy{žyfòå ¥1~S:›ÐtNYyðzyðûò`œ,´ÿS¯ñϘ&çi2§Ùâ ŸÓ þÔšVxwL³É$™={2Ÿ.ø\îL§¸.wà×àz÷.F×3JSZ®Ñ|qFË\ÎÇ´ÌŽV®.U •…FÅ–Œ¿xµü|0ºÓ9ßHédrŠ–ùá'Ëit¯ê‘¯œ+FE•ªÚØ kœ½$yJ¹©u\½%·"9¦ÏîÖ³Ù1¤È¾³Vx¶ùüÏKZ›óM|(ôs×ù9å«Ëñ8-·çCŒ¼Kö„cŸ'öö¯kÈo\SäTª;M¾A¹Â™o]SÇ(‘„oªÊÕÁãÈxjkóþcïM¿õA—¤òÒXãC­(m”'c}@uNªËt}Æ ZÔé0Úz0EA™³÷ºx¸9—àHu^UUÕ7UÀ!|ôãL؃°iL§‹s4ò`GÐ`t}N)pcÐOOçO@_$ó„þDe½¶á˜8 »ÖäšP5ƒ"± 3æè½Í4dï¹tZ ‘ÔŒ]ËQ¦,ŸXXTÈëÁÕõ‡¤naš Ïÿ˜Ð’šL[É…½Ì#Ë–°\KT§,Å»î¶@ŇþŠ@©Rkí™Z1Ü ºUÖ»ø`ÝÊÞµÿ`UÛ|èç•„¬Àƒµ#ë:×7:»#(Ã%ñLUäª`&’G¤}‚€ðʬAµ|@ ÔºÖ¡O¨ FJ‹ ¹¥`1a‰]^ø Ý1Ekí=m´ÊÙ[ÝûæUë>!Ús~à}‡àÊ…{Pì÷û´i^P’$ß+L¿éúYI"me¸¤\w¸ ~P}dŒWºb~:À“msðû®5;qh;n­A%˜ÂLÙõ©&8¨ÉXêžThqGFBêã!k^‰¹XÛQ@×±ÒÖù’¥£ñQNký¥ò6Ó»†Þ MEÞ­ÂCä2ƒ.^„¨0pv»}r©T¶Y±X×{Ç]ç´åF=AÚ^³ì{¥#T&Bx ñlDtÚóô`Â&AtWf.!6³k—™zµþ€¶ý”Õ¦
-"øÇÐÄ €aÀÉJÑ)}!£¼6@Âc.Í[“Õî*B’·!¡k¸Ö_UYúxัLÿŒ=?åËY"Ç~2Ä>ÄåÛôN•úñæè£Yo½)Lvwóê´Òl4^CV^²z¼Ìùã9/ì½Üƒ}¤gç<¨¼•ß„º8¹ZWT ³è£ xD&$äÒ£,[t6Î7ÂG¹;& G™´x>¨IœNŒ#,>a;&šŽþ»b\k8gbðGÆÑA˜á9×€ñó´ͲěeS,ØN©¶ï™j'¸_†UQ"Ã{ö×d:Æ|üùàJÏãTØï+‹ä,¡ê¡[+¼¢±{!Ú ®}I»Q"õšTâ–VÓà?HÅE™‹ ׿û˜Ql\XúÛgž[ Š²·Åe×<N¢¤·ZŠÇ#‹_,Xô¦lÇÜ~OšÆôÃ|€ëÐ\qk8~Ï
-ÿÛßÝ ÝÇØBayà6úIdbGmÖ÷Ø¢díØó§ ½íPaKØV˜Ý*$»ŠÁöêÍ7îCäÂ]Ž¾æ8ìÀiÁ”Û‰2º^´ßÒùY’âÃ".ß¾¾nî3+ú•Ëš-efÓ'ñõ“³ ¾XäG¿Ü1gg3,®òîlÆ°Ðþuð?ST8endstream
-endobj
-929 0 obj
-1506
-endobj
-930 0 obj<</Type/Page/Parent 794 0 R/Contents 931 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-931 0 obj<</Length 932 0 R/Filter/FlateDecode>>stream
-xuÍNÃ0„ïyŠ¹Q¤ÆØ©›¤ÇV€Ä ¨_ ?Û4Uc—ÄAäíY“"q
-endobj
-932 0 obj
-276
-endobj
-933 0 obj<</Type/Page/Parent 794 0 R/Contents 934 0 R/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>>>>/Annots 120 0 R>>endobj
-934 0 obj<</Length 935 0 R/Filter/FlateDecode>>stream
-x}WÛnÛF}÷W ô°iÝlËòÔIkŽÛX@â¢X‘+‰1Ée—K«òñ=3»¼˜v‚
-‘H•2ÅŠX
-€ð"üŽîoß7¸;¡QÛÀ(¨•SÖÕ%í™y1Å舞‘«¯ôÜÞ´>Éócc4
-(ÇÔø}F ±Ô€ÛôX˜=Ž£/Rš=VΪb‹ŽG_2–DÄ-»OÝ®—ÑYè U–Ö(ÊÆSVʇylðÀýÎ÷Ñp h"šq‰Iœex\ùw¸žÈY~®¸L˜½P<àE=A®…÷\ÂýN㲕†—™Ï@FÌ^'·c"v7o`²‘SŒ*Ü“âw”ݤ¶rˆ É
-÷¼ T0œnr­#¢Q­Of‹Ìhð¨Â¸M·;´‰pŸç–äÀÙö”æeFÞOÚí3ƒ~yÙ¶²X¨ ”( :‹sæ]S5Ó
-endobj
-935 0 obj
-1797
+737 0 obj
+1730
endobj
-936 0 obj<</Type/Page/Parent 794 0 R/Contents 937 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R>>>>>>endobj
-937 0 obj<</Length 938 0 R/Filter/FlateDecode>>stream
-x…VÁnÛF½ë+<9€ÌH²`9‡â¶rpÑ‚¹¬È¥¸1¹Ëî.­ðïûf–”d6AaÈ ÄÙ™7oÞÌì?‹5­ð·¦Ý†îî©hûÅûO[Z¯i_áÍýÃŽö%­òÕjEûâ¦:§Ï‘L «_µ'ý½kLab3PÐ6R¬5ÁÈ[ÕÂòÙµš
-׶ÚF5ôüô3ƒB_Ô¤ý±'UÄ^5p¡Bp0ŒúÝþÛbE·ë»|ƒø7^œœ/•Æë‚£L¬)ÔÊë@Ʀ'j€©A„¢÷&K:ô‘‚jŠTsRC`h!a´æ;©pm4…ŠÆÁGQëvúTk¯ÉHÊêœÚû œ©ôîâK—K².’¢L
-¿¸.¡‰D… u®°OÆŠ²Q:Ò!Èfl43t/9k;öÎøÞëÎyèTÊrF“ô/-
-endobj
-938 0 obj
-1153
-endobj
-939 0 obj<</Type/Page/Parent 794 0 R/Contents 940 0 R/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>>>>/Annots 127 0 R>>endobj
-940 0 obj<</Length 941 0 R/Filter/FlateDecode>>stream
-x•W]oÛF|÷¯X (À
-È´!¿«œÀcÌ! HtuýùMöëŒüÉi ô%¢¸K3=Ñë<ºmHém°Ê±H¶ÔcZ–ÚX2V­ \v­Ë…¬UðL¾n÷D¦êŸ?î£@9!VÊþÔ¡IBSM®…1›œFß ˆi¤ùfžFùX³pø2¯¡Bcµ°Jÿìžr(Ô7Hˆn ·8v•¹\ Ÿ¿âlK
-aC“è1âŸTSm©YQ6ÒÿÎÒØ`Ž9ˤ1 ­#4ÈjåáòŽraE*Œ|ü@Tš®º˜ˆî¡O¤¾ˆc8Ô•Za€Ý°  W†XUÛؼe#¹¡·Dk]>—•\¡JE"ÏCÑ\ŸKçG*&º]â3@”æ §i!˶"71’y“)±’ïË£WÂGg62€œd¿,ŽØל¹QÂÿûöÛQ2¿€ŠçÓI|N5M““ø¬û±zwÜ)c>Mplè Æ„ÎK i‰
-ãØäjÓCÛ•¸ŸU¯(¢íctþøaÿ”CéNa hª]j%æÒŠ²2‡31àG*_ o6Ú\>ËJ­k‰¦e*wmaƒ-uææ¬Cµ–m•Ÿ@Ÿ2-„éøšÕ-8´_5=ã£nØR‰ ”„/¸¿.«ëa¡Ö]Å$¤Pý3
-i%É(Õ@Ò iYIœR-š¬€g¹É«ª×Uº°Î'h¥pÐZµ«bqÀÚK˜2À‰k­¬ÊTuÌÇ?„‚u¼Á¼";¨éº±sù0½!.:Ãqt3L~ vÛ¨lxà|(Åq|Ã)/µÌ`<|í÷úÛ+Á=q@ïFµUάÁA5$=¢FéNº¥÷'aÜ=®–׉S1æÙD_9öøf'çÞYow{|¿8zç •RO†ªò‰uQš.mðœ]~âÅþõîòöžî/ï¾üêÓõë×5s|Œ>yÒ0)n‡ßƒ¢W€úwA/ÀëaŠWç1hírYâ¦`Ñ\ãç¨SöýDË0ºŠûÃS-_D½FEªžåŽê»âïïw‚­ÇÝ:âWÈÄ èŸrʉ‡7E*¡T-וÈÐþ¸¾"èuÁ– ϹÞ-÷·-?ä·7-­‰mžîSÅîè
-©<-L6à
-endobj
-941 0 obj
-1500
+738 0 obj<</Type/Page/Parent 635 0 R/Contents 739 0 R/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>>>>>>endobj
+739 0 obj<</Length 740 0 R/Filter/FlateDecode>>stream
+xW]s7}÷¯¸“'2 0œ—Žãĉ'qãÖtÒ‡}»/ÒFÒB˜Nÿ{Ï•´|¬=Ó™Ú Öê~œs ¨ïM†t1¦|}önvöavÖïM§tx±K|èÓÅàª7¤Ñt‚÷ƒ>¿·’|§°³Áóç·# h¶€ùñtB³"œ÷i–w”£B-•e¹#§–ZD%裮>Òv¥òåBÓ\Rípè m¤U‹ù•ðT‰üI,%f«K#
+¾›"÷u0éW’Œ–¯gßÏúÔ\ ÐYѱr!­Å³JÃŒ¤»ue•öˆEx1Nöˆî<â‹ç·ã‡´ññOMJ$ž›õZjöbò+\t2¯­ò;ÊW2"Ž¿PNÌKYôØB@xŒ/€`Äqˆw Šç·W4%̆Œï1jãÞEoÔ£‡®ƒ'¼2šnJ%u+@¤=dÌ;÷Æ•^»ŽO[¹¶PzyŠ:¶˜‹ÓP%'P‹8€þDíÝÍn §ûéë·Ù×^åÚÀ-T°•—5C·U~Q ÎÔ6— Å5NfÜ.E'$ß<úRÌ`EºëÖgí‚ h{oC€&OfA̠ЕJKz¶$—[UA1è<eÙôP ì>Ž'é°‘ŸíA€‚gŸ!SAK+*(Y”ÇK»H B鞸®þ§ëîp
+‰ìóbl^‚$ë@ðs Ùkª¬Ù¨8 ZK¡1?jiwÏtÑÔ0³(A6A‚á9*,(+_ñM é²O• 7!qZ›B–¤3#meYòïÆ9cÒT21)‰
+rùm=§£
+\¢Aâ
endobj
-942 0 obj<</Type/Page/Parent 794 0 R/Contents 943 0 R/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>>>>/Annots 134 0 R>>endobj
-943 0 obj<</Length 944 0 R/Filter/FlateDecode>>stream
-xW]oÛF|÷¯Øú%naÓ"%Kr€ ðG]¨´VuNäIbBò˜»£eýûÎÞiŠ6š¢HàYÜ]};ˆi„1ÍO)-.¿,Fѯ󗘿üñëÁl%4O£•O¦Ñ<üVÐ=?tz3¡8¦Å
-á¦ó-2÷üˆéÑ|²”nDµ–d7’~\|á$ý(ˆy6Ž&û1(ôšNo’%àÙOD[¥¿®µjjzÇIž¸Ÿ\€æy%)¯¤¿Ö…ZŠâo22µ¹Â‹Š´Ù[öôæ,¤=qyO’)°.²£^>ºþpË9ûDtïYrCøÏT¢”¤VîçL• ¶’„–ôEåU^­£Ž£³$šÑtÄ|—”ÄI‡ßï`{4Ãû|ÿ©*cIFÑF<zÚk¡‘×JÝï‡CðY ‚ïË`¯q@6LN²Jõ®¶T cÀOf¾ß #-îéƒæœŽŽvÒ„—ž{¦%¬”¦j45Fj°ªøáê$C¬hhÀveóTXP ßw úx}ñÛYƒñüžMgx
-^ëË€1 s«§ž(s±È"u/é&Ì*0zf1È!ü1a C*ÅŽ¶¢rØ9´v‡‘/rÌbûÄ
-c tÇDxÁç÷w÷” +–̵
-`&h•CݯÈÚYO¡=v¡5v…±Ã®w†¤¥±B[þLHhho†°ÖvÎ>)-r¸#›':³¼Æ`÷´¨° ÛÝLƒ¿ h<ã
-bŒV~ûŸã(ðÛ?9?øe<Š’vÆÆgÔνHF¸-¼ÒÜ’Ø_¼ÚnEµ£Zªº~‘ óÝÕr-tÆ`]ë,û;Të*~ƒZ—yä\–¤ž×üTˆž¼LÞÒÙšB+œ„÷µX"5±©@b}/—hxðXdÄ MUµÔ˜2@DÚ2jÃ&ï Ùfmo‰dŒÐu9còVh `)íVJ¦¤¹N›=®RŒ5
-*¾59t貺à\fò•àÁL¸ÀŒ¸¹_ÆÏþ·Q°¦Tp2ÛܦàDµ‡¨]¼ý…|½ª0P•”᪥ûå(a1p©H/Ÿ‚?vcè#í%ÔJ4…Ų}® Œîô[ÀXÞ¦©k¥_Ì®´—ï?Ü;6î¿Ý>ÆnzÃÅT£™”•îºÑ0Ü ´½UÍù“ Að‚ Œ…‚ÉlÜ'U:K ý)ݤ9µ±|Œ}=½"
-2VÖÆÃÍœæEgm ¹²<;¡'|Kvt:pÊ{7ß,,Ê6FñKÛéJ0Ûž@¦¾Çò)•µ»•Ñu'E—ñðÞ˜\±–úVZ•Ž/ °Î D-ëB°K/wÊóáNpܬ×ujÖñ' ÄèAÉt¥ÊºÁÊ2‡t{{…ëë6Oµ2jeÉgd¢ñ®Ê¨Bâ «‹Îæh ÆÇKòÃÈ÷ýóÉ Gôy³ó'<*ÆXò)Â+x·Jzlág.ë;»j´>^Í¡QÝ£Ðt0lì˜êoRº]êd÷s~‡7+68}ªò§îfb±˜9 Ö:|*á áH<æî‚ök­”˵Ó@ò£Ãë·ÝÃ0f/ntŸ‚ý)$”:Àå«ö Ž7¤Ëþ‹
-endobj
-944 0 obj
-1711
-endobj
-945 0 obj<</Type/Page/Parent 794 0 R/Contents 946 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R>>>>/Annots 143 0 R>>endobj
-946 0 obj<</Length 947 0 R/Filter/FlateDecode>>stream
-x}WMsÛ6½ûWìQ‘iRßîLNœt<Ó8n¬Œ{è"! I0iÙýõ} @$D7eÁ°oß¾ýà‹„bü$´žÑ|Eiyñn{ña{G1þÏ |ùýb/£kZmVQL%Í«hæW=ò©« JÚîqßj³¦mf/ˆi›NžeóJF•ª µšÚ\’.2ÙУ(w‚ŒL»Fµ¯TêLÒ/ÛoŒ!´‹Ëå™Åp§›Y”œã¹ÐèäÂ9¶ÁøoøÚ
-9µ¹Mø«K_‡'}Y +ÛP§'Ñ 0;/)²N—^¶RŽÚŸ¿KYzªêÔÖ0]KT)[ÈG”QÕáTÓ8‡qW¡ñ/¾“µéí´H2—cð;k8 -—Áçœ]€òI¥6zߎ¬÷¶AI’:c¤M‡K5òNïƒ,
-Ñr}d§²årÊ9ÊÄòçyãˆ^½Cðm¹ b†ÀàZ# Àhu:ã25µ^BuÌš®ÀÈôà€¶ygApRqlXyÆ^Öf¬³Tнª¸¾Â"€³QŸç%—
-¯4Rék¥^|g;õ^^VE#Ó³Ýz.×\{Ǩ§Ú¢ÆCß}ÍÛ‰ô»«z¼Å†ñ‰“×ÇÉŒlá–Ù”JñU#Îcrßë¢ÃȲ.0 1™Ny¾VÊêY5ºâ΋¬-¢Îùe™á6>2Ü÷Ù««~„½<uÜûÏÛ¿ò Œ¤óu-ižp3.i1ÛD+¿z3Ï“hƒgkÛ¶‡¹Š>±Ü©…Üw¨'Óigç }ùÖ@u·ƒ0óA/OrbâU¹9y˜Sí Îs*ý¡ªîåI7…kgý4ÖO²§° µ°t¸™Ÿæ±›ç<Ô¹{,áö5fÅáY°,iÃþÏ‚%&E^Šw†·ècœ‰·š…`Sðþîñ
-I9TÙ·ÎÙêåÝ™]Ïg1Íð‹TÛ»w•t²Zc^Ï𚼯<Þ|zwCþ†~‡ÁÐEÆN¬„KwêÒ›$q4‹¼LY”§™rãÕéÖŽ)Vë‹õš`K“eìõçÅ¿PÜ endstream
-endobj
-947 0 obj
-1490
-endobj
-948 0 obj<</Type/Page/Parent 794 0 R/Contents 949 0 R/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>>>>>>endobj
-949 0 obj<</Length 950 0 R/Filter/FlateDecode>>stream
-x¥WMoÛF½ûW zrP[¶dGrzK‚0Ð8n­ =ä²"—âÖä.Ã%Ũ¿¾ïí’M‚"Ž“»óñæÍ›áד¹\âß\V ¹ZJRž¼[Ÿ\ܾ‘Å¥¬3¼Y®ndÊåìòO’Ó÷¹ª]Ë|>“OÖdF§ò‡Û:ëe£›Nk+ŸM]çå~ýjýÏÉ¥œ/®aâTÙT>Ýßý-­7vËSäú›ã ý_Íg ‡¸x»ñM­’&»†ÛþØbÅCw¶ÑÛZ5ÆYqY4O?LR;ï²fŒ4yíÚm.¢¤í#/¹äŠÁ#òi˜T×ÈIÉ/¹+öë¦ø¥Od~c3¸£‚Ûj«]ë7˪m˜—¶;S;[jÛxÉ\ K…ÃóÆ”z&ŸµTµöx)1¥eŸÒ©tc@†LOÏpŸÆåäØäZU¹Q“˜|k-<Q!®Z•^–ï
-†,î>Og7….Xô.¨ŽæµP)SVx ÇaŸ8=âü×Ã{ITQø3y(ÚíVÁ¬¼m­mLïpi[hœ`‰˜Ç½*ò£®w&AVi’œqÂŽë†ÒM\Þ¯%u¥B iíÃñªÒ
-@ê«4è
-8g¥y8kmBtUaš½˜†àï@!$™#<€Ð*3Û´:C`ˆ²Õ¹úÉ‹‡k(ö3¦úûúÍ&¯çoðûúf…ß ü¯ákèÍ¡W®o^>»M³˜ º¢Ô!0š¼¸èÄfŒëtQÈ“uØ‘«æý“«€MM–¡C@ÆÒ¥ºˆ¯uÏjâº0ÍIá¶è¾
-Ù¢'ÊÈBÁÓ#›NrëЖÕ`÷(Ø#ª†Êe…иRªThf’¶h@‰‰kBL™Ð¡fMç$–“à³EŽ§AWïö¬Õu¨áZ΂z}´š}X‚I‡ŽŠ„»Tí"þ&µ$ûQ[±àzÚc“$®¥<ÀØÆ5 <˜Øú5ôeÓ!àÀbÆ;A$vþ¸ñBÏCÉ ú@W5P”†½ÅÔšv€ÈïÀ÷
-H¡<fâå¨Òª´Ä@âžC#`‘á|XÛŽ°Ì@‚ƒìh„ÆD{”ÔÃÜëŸ Vˆ ÂS¯0ˆNß*ªÊhLjˆ‘É#´€Ãù@ññØ›¿YΖ?{óå</¥{WXa8ÂÀ#®•òÐÏáÈþà‡ù7‹õ»1ñPE™æ@PÛ°Éó º.”)Örã¾Qm¢œsY[¬J]n€6PPØŠûýe&-¶
-r}èPÈMü*Š[ê•Fù‰±ÍDÞéD! ss¶ÂxîE^€ŸŸæÜN"_NwF…ÈîÚ1ñòˆß
-endobj
-950 0 obj
-1670
+740 0 obj
+1527
endobj
-951 0 obj<</Type/Page/Parent 794 0 R/Contents 952 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-952 0 obj<</Length 953 0 R/Filter/FlateDecode>>stream
-x…WMsÓH½çWtíÉT%Æ_$áhÈn-‡„,1‡\ZÒX"͘ÉZí¯ß×3’?IJ@ÖLw¿~ïuûûÅœfø5§›-¯)­.Þm.^ÿ±¢ùœ6[|r}{C›ŒfÓÙlF›tòÙ+çɪ EŸ>|¥ŠÓBE)‡‡†¯èa#9b“Qîl³#2\)OìådG­mÊ,¼ú›áZïÕoñ¶ðÖôÕæÛÅŒ®æËéÑ'9!÷§…m mu‰›È[\Åu¼"|¦2J:‰žÙŠuÈEÒu¤öÊPis<«åœ¢óì%QטQ`Ž/}½ú¢Mf[òÊ{âQŸ†^\OW}ÂÀ¨ìÈ&{mO8®SÔ€Cθ/Á3Òž¥M.H„ÿÅ’FØEèj~Q!ó­uÕ(Ñ»÷ëÏχƒ4< èOiS ~•¢vÔ kâ²´­?äl2U+WIGc.NeÚ©4æn‰G‘{ SkjgË=G”–Mz(pÚ±«uÚ”ì°/ ƒ Ý:-¨v—Wûkx8µUN™Tecl×Y¦%dÞ]ß9»×™ ÝiÐ_ƒ˜pðp¯Ó¡œH?z<–MžsR*ZŸUyo³FH÷<y\ß?¿"ß!ë
-Yê#£î5£ö#ñ&›Žpœ”‘€ïveŸ¥-…Mylj.uÝíå sç+²[äaÒÂY£ÿjï[ë2aUÝ*P>&êÉk`)Ý>yG4ãk‹‹9`AËzŸ'½ìhùó«Ð¤ß7ð z³œãçêö?øƒ(Ûh+oiyˆ­¬ÞÞie>Ÿ.§s À.W5}†ÔŒS/ºZˆMN´S‡—‘?$e]ÎÀ!ô\p£‚÷¨Ù©¿µ¯!ô#a‘ÚÀ7³uìA´ng EOLxΨ­öElyƒÅû€õ‹¯û »P þ8=вÕ@<hL:c§)zÛ•¶ ÷ãÞÞ꺰ˆ‹š¤Р΋|Åå¡2®QmšÚÆԨ䴰^ÿ¹S\ÕÀ†
-ÌÛêH¨QXΠ~à…ûàËdQQ¡8ºÅ\%~(ÿ¼þ
-MÛÁvPJʼn:e°à2w,œv À6f¢k¥1$€Þ¬ÿînP°Ì•`M;‡¼B3áà’¥{:ëí¶îéc /éQè0ò
-‚7áÀ£Ø_ñáÉ+®`'Á‡T.@CZÈ?È;¸‚äé(Šl=ÙòZäõÿ"[.ãü<ÙjJb’ I}‘*$áÿÚ‘Û~Põ††Éê\-c®ÃÇ™ÒR£¯#ùáj AÖAQ@¾`¶áM õ¦ß/&ýõÙyÊXU€„JðP™àÉ>€OúÉÜËØÛô¦Ñ2&‚ÈÜqê{b¡CÀ•E¢ÁÃGb€¹2J”Áúáé)
-bÉ¡AÖ3[ƒN ÙO+ytº’5ï.,£"ß·5l4w‚m–<ëøZv)Kb!f[bßî´*3Г)±¶Û-…þEËúàЂr°øQä]ãv³}¬”Á€˜ø@¡Ÿ¸´¶(ÓTA«Ãôx!pÑcXs£4ñ¦MÂ\Œ
-B¾˜†Ø™6£|8‘¡*ë9ÖÇ£$ô,|eˆWNé#
+741 0 obj<</Type/Page/Parent 635 0 R/Contents 742 0 R/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>>>>/Annots 108 0 R>>endobj
+742 0 obj<</Length 743 0 R/Filter/FlateDecode>>stream
+x­WMoÛ8½çWÌÞ –-ÙñGo ºéöÐEwc  Z¢-¶’¨%é8ù÷û†mEIEP}‘œyïÍ›ñ¿W)Mñ/¥eF³åõÕÝæjr¿¦tN›=Þ,V¸(hšL§SÚä£E2OèzóýjôUŒpJ7ä4í®éAÔ;AY2MžùY–dÉ3:¹ŸSš†ýÆÙû>«'‰…¥pÔÕ8i¨0xf¨8ÈZ6ŽJa)/EsmG'I¥n%©º5úIÛkR ñ)„[ÃûhCFVRXi?Pãã¦4NgøGûPECòYY§šYéŽm0åxC{]Uú„ØWTÔ
+WÚ„þF’ÀŸ+%µÚZµ«$Ù\6G[¬2t9õ# HÇ ãs¿ìéE©ÐÔhG…´ªÛª‘'zTM¡O–þÜP
+Ë™Œ{¼ñI
+Ú UYRŽè¤@Rat‹ìO¾dŽ–éì-öBè¼PTÕ0a­Îâ) ÈÈêöÑopbHì&&]ƒ“:ÞIÛi]…De5Š¦ˆœ“Ù‰üÇIH,×5„¯vªRî…y à3bb5×#W#gÓÈg‡*þ~)ÆwÅv“AR(‹Ÿ‰m±èj¬$`"ÊY'>jI&‚¡ÌLgF¥¶v¡y@uð³½f)/³žÊTêàk!C/ïÖÈ\²É¡ÐÃyºÒH¨½L>o{á¥#è¨C£70ÕäÕ±ÀwCfýúX(^spUf6úªF£›ü ¶Ù:é7¬±¾ï…ÝÏuÒ©å§e~ß/Áüh Ûµnª²º:rSˆEyË:ÚPª‘D6ŠÛo\j‘aFOCyÙ3Ø ;>ó‚Ç~ìÔÀ×æFµ(Š!¨¡¼BŽç²@‰ç•B°áùŘÔÁ·¦Íßýç?€x”¾ ”xhÐMX+áß\qóô”R¾úû3úB2¥ù|Ž¨)]fɺ»«è;ð`…9psžÏo|É\šqé\ûq2áŽÈQ$ÂÏ%|I#Ý„Ï¿l寰\µé• ê–ý/dþJgQG=EÓõ,™ÑxáË÷6/ݱ9üö&URÅÿ4OSôÞùj‰ëtKt>Ÿç¥Á`üXÝ â/Ém
++?òlï’w‡Uã°,ü¼øõ_ó%[¨/šÙMì_Wÿ ‚Ôendstream
endobj
-953 0 obj
-1691
+743 0 obj
+1405
endobj
-954 0 obj<</Type/Page/Parent 794 0 R/Contents 955 0 R/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>>>>>>endobj
-955 0 obj<</Length 956 0 R/Filter/FlateDecode>>stream
-x…XMsÛ6½ûWìääÎØ´%»¶“›ã439Øu+eÚ["A‰1H0
-–VšŽ5¯º ÒÙšŠª,µC|S¯¶s¹FXŸ‘þ[Õ­ÑgHÏØVÆ6šb&[ë^ð¥„U«]o>åu€8„ í*ÄhK¢Ò¨©ã²2xèƒu©TÝØ\’'R­Œî©Ñ]ãÐ8”a‡ƒÎ£˜umgRþAL“¬%‘·3’R"††rÛøÎÀ.=}YP¡‚Z¡Ö„¦—ß)úô´à\_Ñ9Õ7kâsÔ×,=šßd Öˆ¸Å‚TÛš*5n];U׌ª Ú•
-ÀÈ¡mÕ¬*ôž“p¼6%£¥—®ré#ªþ;ÚrΩrìK`˘¼IYÖÎv- B$·xìÑ0 ~ˆ,Up”äħ]U5=Û*0ô´ì‹×yöÿ¸øýù@0ðÁéÙת@æ@Âv”˜ÊsÛaÜtÓÕ2c¶éËÚOÔW1‘ìP,IÍT+§Ü.:ÀLà¹j3<ÐZ§+æÎ
-®Ký÷èeØØn½á v´Å
-Øb=Òà.rù¾¡ÛÊ0Ú˜«Uˆ“j[t†çÎÄm€$\à/°÷—ì‚Ì |ö«úâŠË«]ÄO4yhj´\Ù^o3m¹c«Ü ¬»IäÅÍ+³‹ñk@l~ÊE
-!¬v BðÜh]p擈ëBäB€‘¶ S¤$Œ$Ê=îçH„qQÒƒ÷”‹
-z—L½‹qÇs0ß& #‘“Êë,ÈW ¢Á0H%Ãf¨!rî[Ée ÷È.Ò«_–'Pº4¿¹‚’¸¾»åÏø Ú)§Âx>ŸÝKã«ŒžM·^«&ò¾ãZ„^ƒ<Êœ
-e퇇]tò[× #·ôÒØ-Êëéùþ*Ý„>y {åƒS˜ì~uè O0Á¬«þ‰‰‚Î75v ÖÌP¸
-JžïÕÔé(!^ñkÈE~çÁ›a…´è9ɺOQJÒC”w†×ÿR`ƒe‘+XË7ªY $+€ˆu : €Œ]!2¿¿YG/’yÀÞøIïn“8Æa¤:öK%?*¼BË2ŸAŽï}×*ú½Yì6v$S[UgůóF-ë^¼1RŽ˜š÷)2š°HEvJwÈ£õ[+¼°á^ගjnñ<ËCŒþ.©¬ÙÍm6Ã/ïù%pqÿøñí´ß¸¼ŸlŽ÷š$þøÖy<|~;ÇÏÅ[?k\ß^gwø5'¾âëX¿ü Õ¢ª”endstream
-endobj
-956 0 obj
-1820
+744 0 obj<</Type/Page/Parent 635 0 R/Contents 745 0 R/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>>>>/Annots 115 0 R>>endobj
+745 0 obj<</Length 746 0 R/Filter/FlateDecode>>stream
+x•WÑnÛF|÷W,P`
+ škÜuÊ~£ŸhFWqxªå‹¨6è¢HÔ³ÜÓB}WÜýàýN°õØ[Gø
+Ù€¸ý1g ¬xxS$JÕrSŠíï.:Ëë+‚^—l¹ðœëý‚°ÏqÛ²cnpyÓ²1a“%‡”¡=:Àc§×ÉSl-w$ì:µ­8Ù¯bû  Öø/ŠÌÎ4~õŽT¯©ÅD„tÛ°1ñ<ÉÝá6•ìRŒéýú믙¼R­»šiduj3šÜDã‘$–´3¶A&páÁ rc9 v@|…¸>LfáŽ?=›ÂñݧÎñ¡ØÉÙËß«í):Á‡J!%m-–Kr"ö¾¤Vì—$³¢qàmu¯6Àø¦ @ˆ+Ýê18{oì§6pÒà*ûûR9ZŽ˜¬Ázà ß뙸ÀÍœæ3ì¿Š¢ùÔèi˜ŸÙ ÞÁ»
endobj
-957 0 obj<</Type/Page/Parent 794 0 R/Contents 958 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 146 0 R>>endobj
-958 0 obj<</Length 959 0 R/Filter/FlateDecode>>stream
-xWÛrÛ6}÷Wì[”[¶(Ù’ßêÄuⶹ4V&}ÈL"! 6 0
-õë*ËŒ]Á$Y½íÚo Ž.§oÆ. \l42Ñ*ìNIå9âA¨Vë !Ò…îùÎò_9ÇÁóóó;À'` JUü½¦‡ÁŇ-’ƒb©+zÎïyÐiíMµ;ï[`TØíç›LjΊOw€ò:×e+j<^£`™ª¢kdì¶/ðßEmô QÌÆaæÒº@¡b™ÆÂùéJ™< 9˜_ç'  ]%ãá„&³)~OðQ,#Ë®i4‰,»œ]¯Žx6 'øÐW„/txçØvK7ˆ;’åäž0WßÀ'p æ›(öJ.2ê^Kîµ…˜™Ûú8—’˜Š)À†„\=8™#Ü)oPøŒiº4¸û}ðåþöûëHÃîpD!7«u•ï(3Ë¥ö¸Ç|úúñþ/PÚ¤kZ+”ƒ¼²+MnÉÞÚ7Äâ2qðÂÆéN²  iC 
-ï÷Ýs×° 8Ü_Ž„!ÝWL¿¦¾¯=ºD÷¢*BVÒ£©Éöq±W’îÁ± †DŒqÏsc5òÛ.ͪöȸÂã
-
-3W¨ Ö ÷µFë=ÖU
-q(x]ÕÞÂ!Sôùö­ˆBÂwøªå®ÊX´5Õ§Úˆz<oâSypÜ›aáL`9jïþv›Xj,„ž'UtÚmŠ-TKsk)µçô0-:Y1ñ„[ä£AÖáûk¹~. *x*ѵubò ;èÑ‘†žk‹ù‘º2‰ƒj…B°
-IÙ¹ÚÓÆÖÏ´pÏ8í!ô¶Ï÷NãF‚ôùºJôæË ù©GRÒù¯<¸\y† Ô)Ú0=æžíoáà{Î+Ìcù¥¹}†ÙÈ;ÿ™€5¬ž+v|ôAHû¢qWCsxnL
-[ì0ú²÷xš¢MâXë£Ó õ½T ¼õA” n¸$¶;d’7¼öU1¾ˆÉês+c'2 †}…Ù`1‘ú¼“Å=ù]† /O¯¼^ÕàÇ+tH¤ø)†ö_¨2ÚÏ¢°ÍCw«Û3v_¢ñÅÈÁö’äw~7k^åFWœúÕôr8ãe(žýìÝ#ºn»oBßY<~6MðŠœ þï«Ëd:y¹r9a;ÐÇ?Oþª—ö"endstream
-endobj
-959 0 obj
-1766
-endobj
-960 0 obj<</Type/Page/Parent 794 0 R/Contents 961 0 R/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>>>>/Annots 149 0 R>>endobj
-961 0 obj<</Length 962 0 R/Filter/FlateDecode>>stream
-x¥XMsÛ6¼ûW¼ž¢ÌH´(Ë–3=tœ4i3Çn¢N.¾€$$!& • ­êßw iŠuzédK&ð>w÷=毳XæøËj!W’go×gç–DzÞàÉÕõJ̣֙ù|.ët²Þ'¿ß}[ßÉN9I´.åP™ºÆÏMe Qòê‹Î~Wõ,Õe]™ô•ìuåö:­Í“žŠ³b6"GÛˆª´4Δ[Q¥­wº’Ì8\IšÚØrúzýýl.³ø"Z „ oê·OZj+…ÍÌæ(¸'¦Äµlé
-}Ø©š‡6?p​0pêA¶ztýœ¸jSFf‹«hI—ßvGq;Ûä™|¤µÉÿŽ§íñÙ*ºF™pøaqµ’ð°+ŸõÆ|åTžÛƒó!}½¹}{#*+LɬUm+ú¨t~[ú#¢_Ö&UÌM
-îN®;ñy}þÍ”‹O£ZÝÿúN6´‡ÔG6Än$³…24W$hM$Ò™A;ð )­ä¶Ü¢!¥Ö£òEwz¯§¦³Ù 3*MmSÖ}P!3XzÒUÔ–¤+/®=W×vÕM4òV¡À#À´)øÿ+v€)Íig¶%2aMÜÑÕ8ž5ø¸éA)¦Øçš0¢ʯ
-Y¾‰Á åõ
-Ÿø ¢o‚²¼‘Ô¢²,/WÑÕ‰¶Äqt-"ù¢ÿjLåëïN EôP&m³<,r-%©-7fÛ Êä
-[…øP fI©I›ªBKÑ— :Q4çäíÍ»Oòq-ÞÿtêxÒÂã>9{Õ ôq¬òt„ú‰$*}”fÏŠµÏ­‚LÎužïUeÁgG• ä°‚lÚ
-#9Hlí~—'hùªâ‚Rf ¾$ÖÖTÕÇGt{óéý(ü»ÏïåóÝ·‘eoµóz}05ŽTö uw’*È‹z„4×ÐE2€S·´…0Êí¬à'‚¾PéΔ:òØ}åä°—–]<¨Ò«:äBÑ.û}qɱ` ž½5Úg¸8I]ãÄÀE@½ÒUÕÞsÛ Ì@?ñ&2nG'桇£ŠÁ#Ë`+³5¥ÊÅÕä8~u”ƒ†DÐM»­®1!/õ¢¾„žVH~ë<J·AâŸg¯[g`®á)‡}W ”Õåó  “îW Ph!˜ÍxæÅ”ã6^O¡jQš7DêYSú©‰Ç¨L „ÆØ 0ö%æ?_~;‹Ëè\ÄsLµBâË(¾åò•ìžãkŒ‡Ã}!Sº°%ò¹Ï!#”ù :Ñ–ùÁÕÐ ¿YFÃÃï…,âË·ÃïxzqŃ» ŠÑ?çQm¥Ëc*`ƒv…rtloƒþö¼X˜ áSÁòãò¨¡¦±¤¹…
-JYi!L¢ÓƒïJ·b„QQ avBjWn’JUUAeTY\£)Þ{Ø€ãh)T'1§¸ç¶ …ÃØ_EñÔïì«*SMÎù„]Ka7¥ñó½Ö ‚Ù<Z-g‹ExÒkMë(!šY“×n¼CY±Úìt¾ß49¥rîÖôŒ†™~Ò¹Ýs˜ÓGàÙQ‘^ˆÂýQ,<ßöÅüCû¿{¼ZŽDÀö ˆ;Ò¡Ô`¦ÜÝ5¾ÚÃ×v¼¿Õ pQ«Š¦#HI€¨#0ÃZy4HÕn6d‚O9°%£NfÔÍmÊ’Žûn¶»©|j 0ÅÄi.Té²› ®HÚùÜ7©›©ý)_:D¾Œ µö9ý ߸DxÔðu‡ühÃ(@zð<¬~"2þn,ú뎷G)ñtxu2XÙ2SUæ¹Úbƒ{+ÀP vv&݉köXö|DÝæÒã÷Ç£òys ofê_øõcˆ]!VIÆ–¶í{aRD¸¾õr„ÕÀ®0mO 1C¡i+û9ÊÆUçx£¿î»Çã§'
-endobj
-962 0 obj
-1952
-endobj
-963 0 obj<</Type/Page/Parent 794 0 R/Contents 964 0 R/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>>>>/Annots 152 0 R>>endobj
-964 0 obj<</Length 965 0 R/Filter/FlateDecode>>stream
-x¥WÛŽÛ6}÷W Ї*ÀZ¶d¯/yKÚ¦ÈCz[?.PPe1+‰.)­c ß3¤$ËÞÝ´›&€Ö6Éá\Î93úkÑÿ#ZÇ´XQZMÞï&?í&óp³¡óÃìñeNñ|.i¹Yãób®ÈHʱwN·«ž~Å}t+°…E\0<`höaKQD»÷®6kÚen}N»4ˆ¢ð6\„QH?è:WûfDQª«ƒ*%ݽûôþÝ›ÝçÉìÃr02Wðj—»Bb§?'¥ëÑYÿ]çÞ)K#›æD¶1Bí‹&×æ(L[É•± 5…‘äÁR%NTë†É×Ïi-˜/­e*­æD™<È:SõžÚî>²)¤!mÜÁ“n©’ï}Tºµå‰’V•| U"(Qµ0JÚЇ8§-§)¢i|ë#4Z7ßùÅÈ/.b¬ wY ÚFsôg§n}¡”¼çkç+ñ€ô•RÔßjÁT]úÃT¤…KÔìCÄ+ g}%M§GÕxÔÈMö­Žqhÿç,©Ú6¢,½ySP`‰Ú¬<v@uTeyC ƒ!mÙÜôG{ÜÕÔ;â9ÌZkf¥NE9³ ‚Ë;‚î€A†H%TÝYÉtÚV²n<¨UN
-eæÛ¹/ιänFpjù¥é#ꦪFUÈ-pe 8˜À*t•ÃÄ2i*ár%C÷ã…A˜éú{Ö°NÙÝ‘û7ä;$Vù`%ê–=Êôß4wf1Ìú`húH¢òÐgé2¼‘º¹€•Ô^ƒí’•—Ðâ…*]ëE^{(ƒ%U¦…¶”ˆôaÒÂ_ìAÜàصåíÓÉ×»òjƒþ™¶¼·e[%ÏPvà|”F”tFT0t¶SèÞŠÃ%{ P4F—L Ta4V˜”¡á>ÿF⑇þÀ¨wö£y'oðIé^E"~ùãçI¼Øbr‰7Z*Š·Ë0ò_Jºã÷ 3cncÞ>F~Q@×áP3iS£Gª´û¥Aõ¸= ”8¿¹ëñ&ôU½6÷oØËó÷‰÷0^‘Ú=¦µgôŠÆ1žý |šÂúälºÁ"Š–á‚V[LYà^¦è7£?Ë´¡Ç3%ŸšF«52]Çîõ¢{5£´,rˆOK¿¶ŽºËõroW]¾Ÿüè&‡endstream
-endobj
-965 0 obj
-1403
-endobj
-966 0 obj<</Type/Page/Parent 794 0 R/Contents 967 0 R/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>>>>/Annots 167 0 R>>endobj
-967 0 obj<</Length 968 0 R/Filter/FlateDecode>>stream
-x¥WÛnÛF}÷WLQ‰")Q’ƒ^àÔq‘¹´Q‡¦+r%Ñ!¹ìîÒª€~|Ïì’ºÕÔ6d‘»Ü™9sæÌ𯋈BüF4i4¡´¼x9¿x5¿ƒÙŒöz…‹’è2ˆi<›â{”ÄÁ˜´¤%?‚Uœ³ûÀþá͘¢ˆæK?™Miž¹õæi¯TY¾ÌeFVQ^¥E“I²k¥ŠBmòjE²²:—«náU¡¢ø“ŒLm®ªÏæ·Û.Ù@Dƒ83ó¬×mäõBàÛÄ?ßAðã} ql-´°’2U
-ØUF‘º¥¤Mn×ôôùÓ>ùI×ïÞ\½~û¼[æ`
-ƒxâˆÚ{UYÞ¤ÿ©*KaœR
-ˆ.¯Û=°Ð§ÍZÂ{o)nïyÁ>6ߣܸCYáy‰›ÅÈÚCaÒV5š>AwÕÆtêÈþœ}••y•‹’ö¼ÐY Ñ=Ì%÷(iHìcZ×:¿Ë ¹Úõ»‡|S
-¼mtÞ¶«î
-endobj
-968 0 obj
-1392
-endobj
-969 0 obj<</Type/Page/Parent 794 0 R/Contents 970 0 R/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>>>>>>endobj
-970 0 obj<</Length 971 0 R/Filter/FlateDecode>>stream
-x½V]oâ8}çW\u+ÁhJB(P:ÒhÕ–2[í´t§Ù•Vš—ð”ØŒí”Aûç÷ØNe Ú§)RríûuÎ=ö÷FDü#ºèÒù€Ò¼q7nãF'iûPs¼t¨ÛÅ£7¼"Š¢aÐ#Åh†µøØCg‚³ÎeÐÝšçÕ® Xë6! ö!vý@ŒpÜ¡KŠgÈg€øqæÌŠÓÖÍíäýU–sÁµQ‰‘ê]ü­Ñ¡v„$±ÐÙ§…ÊØryÀò©`ÚøþÍ´“ìÀ÷g55óCb}' S‚™?5s9„ãša“nGÔîP:Ò™L_¸,ôrsFw´H^‰$gåÊdžpAMTÔ¤D¸o6…pÜ-µÖ\L9,š­’ºØm qMÍ÷Í ÌA{6èß² 4ˆ@fÁH#"i© É>p1'#iÎ Í•,VÄÅLª<1\
-š)™“Ûõ8ºùàÓ©±hwû>€’Òüâ‘
-ØöÀ ­Â¥L“eˆÀÓ$Dᙤöü•Ç¶Ûõ
-º‘oŠCX—eíB[ÚmÓß0;˜ß°ßÈ|U
-꯬* $¯å¥“èç3KM—§M3—Ÿy¶íõÎ΢#±ÞhÃrÌÜ‚m\@;œ,á}ª8iݹã î¡Q·V]Åa!ìt7*óù²ßàe[tí‰Ü¬T®¬ŒÿìŒFlÊ”hÛr’,«ÈéPàâEbm+*„pâaŠh¥äÊŸ›;ùhö½`"eèåý†öØä_µÅÔçRsâ
-endobj
-971 0 obj
-1242
-endobj
-972 0 obj<</Type/Page/Parent 794 0 R/Contents 973 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-973 0 obj<</Length 974 0 R/Filter/FlateDecode>>stream
-x½VkoÚHýί8Ôª~†TB«Dm¤j·íncu?„®jìq˜ÆÌl´Ùÿ¾wÆ6¶n¢F*Hû¾ÎÜǹ¾êxpéëaâc ^uNÂΛ°ãÚÓ)î/ùݸð}ºŒ¦ý×Ûr†”t] G¾=mDn`îEãé´yðÜ#Û¯D‡ )øæBAœSGS€01ba<@ýañR†_;.,
-¿d$åêUwÓ@–?¦6¤¨:à|0?Ä?{H›–ªúæìÝI[á·z†
-VúÍyliLÓwݶ®|x
- ‘9G45oYÖ&þuN*¶%·–{¾õ<{lmš\g2‹r®v›ˆÈô|}P•ÂKÜÊ‚±DïJ&<¥1¦ÉmF³¢„Vļ°“ŠCm;,ß0€Ò]®¡âœ¯ o ”ªŒ²ì‚®FÁ
-QKYf „¼©,Ðô
-ªh)
-ÖÆ`ìo^ìùLùŽ† +>Þ £e&Y"ZQÞ5a2¥æ¦æ‡{~Ã5Of_Lô^+Ú~¸kÑ56Ý‹œ­aÝ ï=Ò@$ò~ œ¿€ŽsPßÁÖ7_Z‚ž£Û']<›¡Û…YËæœúéžYœTĦf=˜7Gï¯&LÑô^•<'4©Ìëf½ž-ó8RŒ¢{ÝMOë•ì­_°‚êõéìøÝÉ1~ÏåWx-ãrE 8ÒÛY#´¼`BêÖħ÷°dPóB¦Ì" u+|(MíG“95Šã#mMôGç?fí¯Õendstream
-endobj
-974 0 obj
-965
-endobj
-975 0 obj<</Type/Page/Parent 794 0 R/Contents 976 0 R/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>>>>>>endobj
-976 0 obj<</Length 977 0 R/Filter/FlateDecode>>stream
-x•V]oâF}çW\mÖ[ „
-rê¦
-a!çkà0¶/Ãßà8œNÎì­FÒºZUÈ߆ùtûè19[E8b¨—±[I™H$9ÿKa<›\ï04`jt(û¡J±ÿ±“•z%Ž ‰ê¬;‘;È0d ²:ã qm
-‹
-Áy©bo¯KmHs:rȪXÂj7R ŽHPef N!2ÞŽ»ŽT)Œ;—2áô‹vi‘–X@3÷{·¥,kÜ«¤&f½7Dgb#i!âMUXÒnh˨•ÊEZ3 ÷™#xàu‰†Bç§d[rOß3.¹É œ[
-´U#á`â[´aÙÞaYÜ~±ŒrkQ%^Ÿ³) DˆC›=-öÀu«=°ÔÈ@Ap’»™Ïh]º[8z8¨ßƒÞÔŠ€çŸ5]B«ÏK;OñH-ÎxüöRÝŸGž4]é¼G\îŸ/ï“Ž6ëByºq¬l÷ˆp >5œÿÄ4˜·VÆ•Qå¾Þ oê#\cM~„àìä̺ž§;8È óE©ZDM¢WfDâ'
-£ #Nƒú­Žš$ Q,[4+Jiã¯ÛÏvŽvF¦WÄkr:-ªµÖOãÖ¾9¾æFÿ¨xvkMkBpiñs'Ož Ÿnïné“ÑÏìî÷:®2xÛÜóQ=ÔFK3\]ìx³5^-}¬œ–G“¬›óã>G£µ_:ÿß+.†endstream
-endobj
-977 0 obj
-1140
-endobj
-978 0 obj<</Type/Page/Parent 794 0 R/Contents 979 0 R/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>>>>>>endobj
-979 0 obj<</Length 980 0 R/Filter/FlateDecode>>stream
-xÍWÛnÛ8}ÏWÌ£ Øò%‰í,‡Ý`l±íÖZ¢m&é’T\ýýž¡.–/m¶Ø<¬I¤™93sæöíbL#üŒi6¡Ë)¥ùŇÅÅï‹‹Q2ŸÓþË­ñ^»œ%SºšÏø÷ÑM2!'i…—G4™O“«øè’fÓd¾r5ãÏZh‚W[™ëɨ–ºƒ'ÓÉU+3™4Ú
-HËU °Q>ÊO*ÐNø߃ѽ1 &×Àˆ"l'¿ÊAoýjµz™N…’¡=ú ÒçÄ[òÒ½¨TÞúÒ™XkÑ`Œ,G¥ij Þ@é>|=MêÚ°‘®Áâá²Bn3ä¢
-ÐÚîð@Rá%Ùí”Y*aˆKT“Õ¨¢©XÊX— ݸvY™Öv­ Yß@¶½EfzÖ‘  ]®ŒÐ]Þƒ
-ßöòÿåi<©=a_qóÇÕ¼WñvœçbÖòRüvJß®:ý°£Ônùöà-ŸÓê¬wÖ: çkñ¾³–õ±U‹,㕺xíÐŒ×C'e§æ¶7×CòZ‡Á³”X° .‹Pm0­¹ªàkY×f#&|¥tJ°kD,-o?{¸Å^â«aë,®¨j#'<¯v ¬Ä¼Wq³èÂ'‹ÂÞßf¢Ô›î©÷?®Ê.HŽ‰·s1þyÙ¯5–!§2>q°-Ø2®E™-pJ!ÄΘonCì] ¹}Ül⎳÷Guu_·G4NåáݼޓÆS^ógÅëøëûOÞÓggŸ°ZÒG›9æq{*©A%ÖÜÒ´>0ÖÅßžþ*ýšñ½Îú{Ó1ÿо\ü°Þ‘endstream
-endobj
-980 0 obj
-1405
+746 0 obj
+1500
endobj
-981 0 obj<</Type/Page/Parent 794 0 R/Contents 982 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-982 0 obj<</Length 983 0 R/Filter/FlateDecode>>stream
-xµWmÚ8þί•~`¥%!,òíhïVB§ÕítÒIH+ÇqÀ½$NýÒ=úë;vH`Ýe»4HVìgÆÏ<c¿tà/€ÉnB yçòóDz3ð¦SØ7r ‡ØŒ¦lÇÓ[É µ3ðO„iîßFÁ2EðpŠ/‰û{
-() kQ@,ô_)ɲ-e]@?¸ñ†Öô#Ë2ü
-šeÓžõ$Y&y±‚thüRy€ƒ¬¥9ä$aÞ¿Â8#Ô(-rþ­Ù,À9‡¸%“°F¶ÌJöÅpÉrVhumש š)Zjo3f”à’
-endobj
-983 0 obj
-978
-endobj
-984 0 obj<</Type/Page/Parent 794 0 R/Contents 985 0 R/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>>>>>>endobj
-985 0 obj<</Length 986 0 R/Filter/FlateDecode>>stream
-x­V]oÛF|ׯX Eá%êÛ}sœ0n¤¢}(`œÈ#u yÇ܇ýûÎIÉì¢b²ÍãÝÎÎÎ ùuÒß)-'4]PVÞo¿mãdµ¢Ó‡-ñϘ³I²¢Ùj‰¿çódBVRÁ;°ˆcŽ¸}t;¦+Ú8z£6y\Ó&»xgüNZ"üŽLã•Ñ¢"¢QpvT©íÈÉ,X壟îÖ×£FÔO_ìvž8“¤äíá©PÖù§F8÷Ëæó`LÃHQââ]î+S*Ãâ—È2´?ù/%ÎÏìÑþÀ³œt]ÿ\LÃÞØüÿö
-£Û¥)l˜Òp²ÀxAé‰Êy.sgÛ¨RZ’(<Ɖ™Ò^é­Ò9&Õ®xC¥ôdÐ$´6¥KÊMØV’kêÆ;*Œí9Ÿ¶Eûž\Ò-
-PÀË—DèÜʯAa;ñäm­€À#_€T Á³¢G0l†‰* ׈»\Kû¬2üÞ+
-šëB¹ÁAº„¹–0iÓŽÞI©i{8&ÝqÙø¢\…ÊBñcLBá<¥³z/»âÄÁÍ]'}äZM
-Jæ`µµqÁÓÑwÝÆþÍŒµ¡ñÀ ¤92ÇšƒÌ_å¾7Ð[Ü÷³¹iM òX™]XƉ×Q=FÙ2îÅ T=ôÏ°Þ„°ÿ‚ŒqÆCÀùWõ9!”V!Æ,cNt”n™m‡df;¿P@œÌ«-¦ -v9§ÈiºŒÚü. — ÝUC¬Õs¯×c>²V{–ú|é“ÜÞæ߶sìåÛvíÜŠ¸Òù™Œ Qk«„ÇîUf3…§O7ÄÂwHëgvCeöQˬ3ìxVðˆ“¢F°s´—%G#F—Î9±}V775Û¾3BZù¶s‚pÒ9öÔ)`‰Gž_!N˜Æœˆñ¢0xÔNÈØáý§ t”º Z}“çMG£°˜Zz–ØËÇàd6~ã1¸ê2(],ñr¶œàïÅ›Þúúþý5=ZóÏeú`²P#3#+Üý°Ý5l·]¼úØœ-g.>öb1åMÞïƒ
-endobj
-986 0 obj
-1240
-endobj
-987 0 obj<</Type/Page/Parent 794 0 R/Contents 988 0 R/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>>>>/Annots 176 0 R>>endobj
-988 0 obj<</Length 989 0 R/Filter/FlateDecode>>stream
-xXMsÓH½çWtqY§*–-&ÜòAj!b–=¤jk,íI#FR¼þ÷ûºG’e¡¸X‘¦?^¿~ÝÓ†øÒ|DãEéÉÕâdp{A£!-Vx3›ŸÓ"¦a0â/Qïz£òR;
-G½µ[*-]ÛleÖ•Óô Ò¥¢Q0"U:]|;R4Þ½3©r;º±©2Ÿ)Míø+vâ3v؇8ðtï´Ó?*S˜RÓg­b“­ý‘ …a}d4çWzeÄÎVÁ¼É*MΟ ¸,7¦ È‡Fy¢U¡)Uß5;Þ«R+<E6…±R-M[SnØ¢$ ÷´T…‰êì±ve]P¡Ý“‰ðþŠtð)RYL•ÎÄ"ÿEÅ©ÉLÁXæª(¶ÖÅD:‹Ü./ÍØ‚À-6º€ÍrkÙé›Å WCJB!ÿúüçIƒ1MgçÁ„R
-ÏGÁEý”Ð×tˆÇ ¼ìÖ²´¹‰P(É÷ 8Ç'M’Ü¡·¦Á-˜"˜÷šä{ÓÇÓ:ªÑlï5¥q8 ¦G1´%±ØT± ù8FT(ËÕZ ŠåƇºæál2{–pëL0‚³&¾coö ×ô8L¿ ¶GvåYôöã×ÅGpü¸XÁ¾.4ž3šœÏƒ!:aÒªiª†ãÓÑ$8l+ u¥¢ïkg«,fƒƒÛi 7:³ï9~gKýZÊ3¸5Ÿ¬Êu$oýÑ×ØÞÇ6ªR•„ߊٽ4™žqR7êÉÄðže6ƒ™Wû>¾¿¹0¨ß]r%娿»[4]}{ùéøzeÑ0Gϯ¢Êµ+t Š-wD›iÁ­/ÙÍ„›½¿ñ
-ÀÆ©™ž1~:AIv´ô£ ,‹´æ‘‡Ì/‘îgÖÖÆh†f@;l­*vC@@Ó2ãÃ〺Ïx;A¨öoyH<CªÉð8‰ýgÆ[{j·6Zë6°ZY€¾xÌ”ƒ2S±±U Ó8A8͈w…â¨mžõÚà°Qøøà6ª³?.XgâÞ#HYËi£˜ü®2OTÄñ©¶)/þ«Û#«@Jô“FÛë¨ràhmí宜.ÑOÞ[‚Í€5 )±/ð\@C‹@¨ºùÐ[¬AØw‹ƒÌ?+‘<öœUXTÖ§>YPÒ¯:¿‹h£d^”½$R±ƒ\¥”Û
-{ñþè ÖÕäV¹aýc  ÆÎêa²(©x(ÕmÄ4¯çÌ3ÆuÇt“5¶tUQ¾(Üv=\~€»IûY,›f×ôòÙÂ\ð€2@J¯ÁLY)["Ü-A,ÓÍÔ¾Â'è^N z](Ôó' 7Ÿÿª-”/c¥šOF‰ú~áfø 2“éçCÿ}x.¡üÜ{<•T¤­ŸaÒ ò—vKí¬ïâóY7†UÕºÝÏsþ•ëÞo`F¶¸*4µ‚
-™2<—KÙ›Õ
-± Š–Ü-&G\9<,·”`©uÖ.90SûFïpR…Mù
-eR¿Óñµ¯nÈwÝ… ËØCCnR*‘‰‡À°…J/BÓF´„òÄ~Hºêm­½1*û>à\ú¸¤HUqäg<¶p ø…U©Š6X–HZ;c„5­Ìé~³¸™xõš…¼¬¼æÀ¶vyM÷)KÅ„ ~bC?Q¬KeÜ«hÃœ–ÙÑÈéÙ±ž‘.£ ÀÜÇ-Æq¸±6kV3“ì8€aŠ\G˨¬§hà3­}ÃÔN,AìTÉÛ“mù aÎ4îš~ËÃzé¼Þ5qhk’\`—ƒÛózžÂùx*7š—üÿÀÑB~ô“9ß‘¤Œ3a(ö­O'ÿÆEò/endstream
-endobj
-989 0 obj
-1782
+747 0 obj<</Type/Page/Parent 635 0 R/Contents 748 0 R/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>>>>/Annots 122 0 R>>endobj
+748 0 obj<</Length 749 0 R/Filter/FlateDecode>>stream
+xW]oÛF|÷¯Øú%jaÓ"eKr€ ðG]¨´VuNäIbBò˜»£eýûÎÞiŠ6š¢HàYÜ]};ˆiŒ1ÍšL)-.¿,Æѯ󗘿üñëÁì4Jh:ŸFc*)>Fóð[A÷üÐÉÍ)Å1-V7Ïh‘¹çÇ´HGwòÉRºÕZ’ÝHúqñ…“ô£ æÙ$:Ý9@¡×tr“„,Ï~"Ú*ýu­USÓ;NòÀýä´0GT䕤¼rþZj)Š¿ÉÈÔæ
+/*ÒRdoØ“›³öØå=N¦ÀºÈF½|týá–sö‰èÞ' ²ä†ðŸ ¨D)I­ÜÏ™*@l% -é‹Ê«¼ZGGgI4£é˜ù.)‰“(¿ÞÁöx†?öùþS5T6Æ’(Œ¢xô´×B#¯•º Þ‡à³8:ß—Á^â€l˜œd•ê]m©Æ€ŸÌ|¿FZ&ÜÓÍ9vÒ„—ž{¦%¬”¦j45Fj°ªøácê8ž@¬hhÀveóTXP ßw úx}ñÛYƒñüžMgx
+Qáe•Ñv“£E[xlÎòÈšTfL·WH£é,
+µmej‘O
+H`Ú {r)yMå¦ÄKÂê„sdJšˆ\SHO2ÇÓš–}J…±ºc¢ ¼àóû»{Ê„KæZ0´Ê¡îWdí¬§Ð»ÐÆ»ÂØa×;CÒÒX¡­wF_&$´4È·FCXk;gŸ”9Ü‘ÍY^c°{ZTØ„Îíî¦Áß4™Lp
+bŒV~ûŸã(ðÛ?9?ø%̵1Fñ¥s+’1N /4·#ö7'oöÑ­¨vTKUÒï1a¾¢¹Z®…Ϋëœe{‡h]ÁoPê2/
+ÝÀü/¥ÝJ鯔4×iS¢ÅU
+}±DAÅ·&ǃ‚]–CœËL¾,˜ !÷»øÙþ6
+Δ
+ÎBf›Ûtœ¨öÐõÁ"¢‹×¢¿P/£Wæ©’2ã\µt¿œ$ì.éåS°Çn
+}`¤½dZ‰¦°ØµÏ5Ñ=€~ Ë«À4u­ô‹Ñ•öòý‡{ÇÆÝâ·ÛÇØM@o¶˜j4³€²Ò]7†{¶·ª9r!Vp
+_¡à1wßÉA•ÎQBJ7hN@m,c_O¯ˆ‚Œ•µñp3§yÑ9[B®,ÏÀNè Ÿ’œòÖÍ' ‹²düÒuº’̶'©ï±|JeíNetÝIÑe<¼÷·&W¬¥>¤•V¥ã l 3Q˺lÒËÝ€2Æ|x 'ë5dZ…mü (1zP2]©²n°±Ì!ÝÞ^áøºÍS­ŒZYò™h¼«2ª¸Çꢱ9Zƒ…ñí’|ÇÂpòyÿ|ñÍ¢IDŸ7;À£`L%Ò¨»‚x£¤wÁ~æª^q³«FkÀãÅúÔ=
+I»Æ†©ÞXÐ&¥Û¤Ž?6?gw8p`à0³BaÓ§*ê.`æ €
+endobj
+749 0 obj
+1709
+endobj
+750 0 obj<</Type/Page/Parent 635 0 R/Contents 751 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F6 9 0 R/F8 10 0 R>>>>/Annots 131 0 R>>endobj
+751 0 obj<</Length 752 0 R/Filter/FlateDecode>>stream
+x}WMsÛ6½ûWìQ‘i}KîLNœt<Ó8n¬Œ{è"! 0iÙýõ} @$D7eÁ°oß¾ýà‹)Mð3¥õŒæ+JË‹wÛ‹Û‹I2ÁÿùcÊ_~¿˜M–É5­6«dB%Í«dV=ò©« šNi»Ç}«Íš¶™»`BÛtô,ëW²ªT…¨©1Ôä’L‘ÉšE¹deÚÖªy¥Òd’~Ù~c ± X\.Ï,Æk<ÝÌ’é9ž õN.œcëÿ†¯5 ²ýþ´û†Ó£1Ñ1—µ ˜¦-2ª„µp§6í!g·øì¥7t9ñ6‰t£RÑ(£©–?ZiæAГҙ9Z¢ûm°NJ;~¬(%Å+ í»^’©»S×›2u¶äDäfÊ‘›3š’¦³93åV!rˆ×|á ö{(¤°X÷RˆXˆK|î[N’ùà¾sñ€»€`hÎïà?Å꧴Ó+ÏÒó
+¡˜WÛÈÒqØ6†Ÿ¤¢(^ lYuÐôõþî/jUî`àÀ_ã‚ã°tLøý·¸Ü·A8…¨V6!ÚæÊRÊÒÄ_ñ, ã]…¦L>ËÂT%ÂK»Zè4—–Œ
+ÚñŽg™±#µôœw÷XctNÎVÉ‚µ´Å"{ºɧ2‡ú²` ½”³ÉèaÿìËh I=€ÌÎDa}yxOi.´†e\*_DÚÀsÞىס:’·Ï›ÌjÏ,•RhëÓj`Õ'¤%mŽI(«J4žz®¦n‘KàΉÃ檲 æ¿ÑtIfá"ý=R‰LÆôjZJQdÙÀü©:qUàkÁ7´WKkÚ:•F§°\<#çq²Bñm_›2>|:ýpû>HsÒ „Ѥ©i!++¶¡îdÅEe 95¹Kø«ËP‡G]Y+[_§GÑ 0{/)²NŸ^®RŽÚŸ¿KYzjêÔÕ0SIT)WÈ”EQúpªiœÃ¸«0øßÉÚ ö
+a$™Ï1øÕœ…ŽËÈà‰sÎ.@ù¤ÒÚX³oÖ»
+÷
+¹92cÙq9
+âø ¼qD¯Þ!ø®\Ä1CH`p-­àG´zq™;/¡:fÍT ``º÷@›¼u 8©86¬¼~C'k;ÔÙ *è^i®¯°à,BÔåyÉ%ÀÅ÷,ÑcÌ|„½p6}ºûÊ`]ZsPÞ‚|æTÀŠ°Ý81é –”t¥›Tƽvê¶qç°mšs‡è7?ÞÝú …*böú §ƒký‰ê½>pZŒI6iB7(ãxŒ€Å¦\uc¨[+¼G±—/ÔŠgàoß6-&ŠPYÖÝ0Ä~….Ã5sR ÿPf¹ß‘¨ªB¡ípÉdB( 
+¯qmrØH_µz íÔw:y9 L{ÌnëA"¸\s݃žêŠCŒ}5o'Òï¾êñÆ'NÞ';°…[fc*ÅwV85Ê=|¯ŠO ˪À€Ädzå…Z)õ³ªæ΋¬ ¢Îùå˜á6>0ÜõÙ««n„½<uÜûÏÛ¿ò Œ¤óõ4YÒ|Ê͸¤Ål“¬ÂêÍ<Ÿ&<[»¶ÝÏUô‰5èåN äà¿C=™I[7G`è³È·‚¬Ú„™÷zy’;sÿ(íçä~Nuƒ:Ï©ô‡ÒíË“© ßκi¬›dO)àjáèð3?Í'~JœóPçìY´„ÛטûgѲ¤ ûÛ?‹–˜AF|)ÞÞ¢ŸàôpL¼5,—‚÷wWHʾʾuÎU¯àÎìz< À˜Ð ¿Hµ½WÙ„@OWkŒÃë^S¢÷•Ç›Oïnè¡6ßÐï0úȸ ƒ•péO]úc£u2K‚JY“§‘r6Á›Ó­›RœÔë$Á†FóMÔŸÿ8û|endstream
+endobj
+752 0 obj
+1490
endobj
-990 0 obj<</Type/Page/Parent 794 0 R/Contents 991 0 R/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>>>>/Annots 221 0 R>>endobj
-991 0 obj<</Length 992 0 R/Filter/FlateDecode>>stream
-x•XMsÚH½ûWôek‰kI 6•Úr’u’Ã:ÙØ·8‡A  D_ &Þ_¿¯{HÄ@bW µ43ýúuOw¾]øäáߧ8 QDI~ñòîâï» o0™Ðþb–<Šñ„ÂIŒÛ0Ž!M ž—XfwÁðáuH¾Ow ¬Mbº›Ë{î’^® ›–…žSYd43©^àw¥<»ûâôcTº
-ÒßU^eZØ^cëÉ&émíd ûˆìÑð HBó ñö§ãÌ\`ëöƒ±Óòi™•3•}c©ï37PNø{N/U&TkâÇò’5Änxi쇸æ„í6–ÒÝÆÞº¬™0Æ„Nìi;KKÄ;_@ì&î§åƒßûðþÍû oØ9ÅõcŽÂ`þ„‡Ç Åà}¢á­º4åºúY07WoÞ]ñèÝÒýÀ‡•îº#s£©^•ëlξi6Í]váýŸ• "#WHù­Ü€÷¶‘!¬ ad4b'5Rl ãÃ<š3ý %{<Ùà9
-;*#OÜë{SNß"ѱåmÿVF/´átàL;Në£îÄVNÅ©Ó€íáŒî± Þ½/vUñˆ­m‚:áŒâ%ªU«Úž<kRëuÈ>î6Ý÷ò5jËA‡ÍÛ"ß?ëøÌ‹Äg.LD8ƒÞã|ÛÆ¿]ÿ8v†ÁoŸ”h+ Wª®±ŸæHB\7PX¾­S£¹–»$Å©© ~‡R·|ä•œtý(æ
-×Fߨß+?nFqOZQ¯«ª4v»C³rYø…þ>>p*úN®?Äç~í§7å)˜)É(ÚµåR,ñQ™r‘fºþ«C-ö0§4HD8µ Û& NðjWÇ)½Çßo7÷÷[ Ö<úIŽx®qü÷šVe®iŽI`Z äE7¨I©Õ‡…jÆȺà˜S¶cvqCˆÍÌÝ N›DñA@9³ç&}8Q ÞJ…ÝÖÅ`Ìåµ!Û g´Ž]ÕßdžÓÊ|œ&›G¸
-}’êºÒIº
-4u­.¿ÅÁÞ¬¶A~ä*EÈYË § òãn¥8½—†ëÚ ¥˜ k>‹ ³t6ÜòÛÁ†š‰•þÇá Žñô€XœUÜÑê8«õÙÙMŒ;áŒÒprP6¨q=rívõOt~…Uó<•®þX·õÜž¸•“"·Á´(îÃûÓ6UI¼U¡œ Äµ"œ±Î;,Dgœ‹#êËMü°° †¶S§#G/÷´rZÿ”+f»¸ü„G‹²­)RzyΔrZádtÐ6Èy‰XÕ_‘y^[)B–;÷)°ÜŸVŠ–ö „îjŽ±Ó»?'õ¥Iæã÷|~çEú”í?Ž[傪2-¬Õq8^á8ôÎdîX¬f8æò1P> #6G¸áõ¤9 ù(%>>I°#¡áöꟗWôÁ”_PÝð]!Ys#$™‘¾Þν_þ&¢wÂ÷žŠÿ½øÇ{†Êendstream
-endobj
-992 0 obj
-1578
-endobj
-993 0 obj<</Type/Page/Parent 794 0 R/Contents 994 0 R/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>>>>/Annots 228 0 R>>endobj
-994 0 obj<</Length 995 0 R/Filter/FlateDecode>>stream
-x¥XkoãDýÞ_qUH¥Æ‰“&éò-íRXÄ>Ø Bˆ"4±'wí™à7 ¿žsçáÚ! H¨­6ñã¾Î¹çÞÙ?ÎRã'¥Å„¦sʪ³›ÕÙèîŠÒ”V¾4¿^Ð*§q2i• ¾QY}ØY™ÓN³×un¨jŒ¥µ$©Äº”yBt§kªt-)—V¥!­h«÷DVS®Én sIµÜÈW.VϾY± ç‡RþôþÛ³é<Ó|1I®©¢tr ÷­¤èÑõƒ x1Åó½ßܾÿåÝêÕÛ7ÉÖV%»{~Ó}›ƒ„øÆè. ¹0“N“ l î'óE¸k÷‡“yrÅ÷W[IFÖÈÇÃ4»®-r­D¡¨ÔZ*'Ì è®ÄúUIëøÍ ÈlJx", ñù˜bÌÇ1 ‹0CH•0Ñ®k½Gà„ %>l€ÜÏ…Êq™(+ ©,ƒVêLXo ä)+% £Ç—·€þ])…‘-¸Î磨 ÝÀàiA™OtÃn õ€h²¦‚a P¤PYÙäàÖ¾°[ÇÊ cëbݸûîÈeà×Ið"8'À‚LΘZ(åÒÐQ­Mp5×ÒÒ–ô†ù)(ÓÕ®”ȾàŸ£Õz¨u³£JìvœÌÙI©Úú½Yùò8X~5™Ô³ë1ˆSÑÕìºýI›©cÕsÓý¤Š§hê~ÀÝCø­¥(ËýшÍY0H9ã%Ÿv%3¿<b.šÈäýÅ%tך2ï£äJÛoBn O˜>Ú…fóÊTÑtœLÃŽ½óµ¢Ù,yѹÇÍŠ¯\ôngŠ¼B€®ˆ}çmW’©ÖI¦ÕrS‹
-(xŠ
-\¨<k€C†ZX†àü¥ï¸%[6çdì¡”$²L7Êš¤›Ål*_]/Ñè´W¿”¢©7ÐÅÙd
-ÍéFœN’«„n£»×"ÛJÒªf \7®Ñ¿×…âˆn]íçÒDÇÌ=ñ|´|ñYtÇÖÜÁÄòæ­3²`èEàk¼d·ÂòõÆxøE_Ê:>0ƒ}Gs÷ƒZà>´w+˜x«¾¿ˆ¡Éóñ?¾çÑݯžÙ (Pc é:\ú^E
-eaq„UI•¬ÖòXš !µÌr¡‚Gb×6†³ý êðŒÜìcc ì•>‚>þ(Ûà’>"ݲÍçÝË[è¶CÖBÚ++(£‹ð^>ðD: @ËаsÉÛ Wäò(œ·ïìA4Q[ ‚T7`&Æã×nòck·Œè0PáÒGŸÇÝ æ€!fÑB½æ6G5A˜¶ßPÔ-2¿€ó5^8ôÑ]\L:í v¯åþ‰vA¹¿HÐ=òH‹(
-g_úÞvýŸÖØó·jæ 7åá¼Ò3ïúIÅYï¦dc± ðdt"òËF& s\måÆå83Ù«¶Ç•ox…qüÀ®gÆóäg°Mð<’Š—Yl-[3²«¿¹ë—±K`€uàCU7†O'>`9˜JHщÚÆÛö?aQ:ŸýëÚ“NÓSkOšP`Æ­Û 2Ðø×'W QT
-Ôׯ4(
-endobj
-995 0 obj
-1869
+753 0 obj<</Type/Page/Parent 635 0 R/Contents 754 0 R/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>>>>/Annots 140 0 R>>endobj
+754 0 obj<</Length 755 0 R/Filter/FlateDecode>>stream
+xXMsÓH½çWtqY§*Vüm‡[>ÈB-„@̲‡Tm¥±= iÄHŠ×ÿ~_÷H²¬À!+ÒôÇëׯ{øq2¤þ i>¢ñŒÂääjyr~{A£-×x3›/hÑ  ð—°w½UY¡-zkwTXº¶éÚlJ§éA%+E£`D*'uºüv2 þh‚ó½{gåötceR>S8ÇÚñWìoˆÏØ_<ÄyœXÀîvúGirShú¬UdÒ?1¡á°:1šó÷WzmÃÞ–ºIKMΟ x,¶&§ÐFY¬U®)Qß5å:Þ«B+<…6±B­bM;SlÙ¢ä÷´R¹ «ä†cìÚÄ:§\»'âüåÉ*àS¤Òˆ¶)ŠEþ‹Š“šœ‘ÌTžï¬‹ˆtº}V›²A3 Znu›ÅβÓ7Ë®…„†üëóŸ'Ãá Ót¶&”Ðp1
+.ª§˜¸¢<^àe»’…ÍLˆ:I¾OÀ9ò8i’䎸 ß‚'‚y¯Nî±7}<­¢Í^'Á´CcQ‹uë»1¢Bi¦6ZP,¶>4@Ð6g“Ù³„g‚œÕñu]¼9€^Ñã8ý:ØÙµgÑÛ_—AaÐ7äb‡ºÐtºf4Ỹa
+èJ…ß7ΖiÄöÎo§Úh˾§ø-ôk©Îùí¬®ÅeYl­û#'yëÖ°ö@Ð>²a™è´ üVLî•I•ÐŒsºQO&‚÷4µ)̼:tñý͵`Aýšç’ú+©FõÝݲîéÛËO¯@×+‹~©=zzåe¦]®#0lµ÷ÚT l}Én&Ôìý¯€gÎQù(2g¬c‘qÚw,‹ËVEà…Û ‰˜B•©•‰Ma¸G,©°õ¡¯&ì°,i‚B P'­ƒ=ööã)2ùÊß  Îh"¢¢ª‰3`V¦¡FÀk„ƒT3(A>:ôóbëŽãÈËal7œöÚÙ¤sJ ®S(£ßÃØ –¹(Ô&„NÙ²ˆMÊ  M ,YN©†å,»§ã¹­h>GÖlBî0üN¨r8\·ê É„ê;‹ ?‚Ç
+VWÉ$VfÂqT BÇŽfÜ“ÁD$j<BüS#Q“Á´#Qk€Ë<U¨ïžãZ‹DK,©e”ãØî@«CÎ ¢e’ò3!èÑ—»wÿüûîîayùþ}°-’øøæã2'xLð׬Aó1Tg|Áó*¡Éx «§&£ñóµ-ºONæ`ãTÏÎ?ƒžÄ{ZùI–…ZóÄCæ—Hw‹3k#4C3 ÌµFÛ!  é*ãÃã€ÚÏx;A§oyF<CªÎ°›Ä‘ü³Dc†m<µ ˆU› XŽ,Á _<fÊQ™)ßÚ2Ž„iœ œ¿fÄÛBÑi›g½v~Ü(|üü6¬³?.Øe¢Þ#HYÉi­˜ü®‰2‹UÈñ©¦)/þ«Ú#+AŠõ“FÛë°tàheí宜.œÑOÞ[ŒÅ€5 )±.ð\@C‹@¨ªùÐ[¬A­ØÎï–G™ÿ~4V"yì9«°§lO}² ¤ßt~ÑZɼ({I¤|¹J(³14öãýF'Æc5@Ži•Ö?ò˜`,á¬& ã’‡RÕFLójÎ<c\;pL7Yb WæÅ‹Â=b×Ãå¸Ë´ŸÅ²h¶ý@/Ÿ­Ë9(è
+Êù5F i«?¶µæ2ƨú€séãŽ"UÅõ‘ŸñØ4Â5àV%*ÜbY"iaìŒ!Ö8´2§ûÍâbâUkò²Bð
+˜#ØÚåy4=¤,2ø‰ ýD‘.”‰qE,Ã-sZfG-§g] <#]„A€¹;6Œ;ãpa­9V¯f&Þs
+endobj
+755 0 obj
+1781
+endobj
+756 0 obj<</Type/Page/Parent 635 0 R/Contents 757 0 R/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>>>>/Annots 185 0 R>>endobj
+757 0 obj<</Length 758 0 R/Filter/FlateDecode>>stream
+x•XMsÚH½ûWôek‰kI 6•Úr’u’Ã:ÙØ·8‡A  D_ &Þ_¿¯{HÄ@bW µ43ýúuOw¾]øäáߧ8 QDI~ñòîâï» o0™Ðþb–<Šñ„ÂIŒÛ0Ž!M ž—XfwÁðáuH¾Ow ¬Mbº›Ë{î’^® ›–…žSYd43©^àw¥<»ûâôcTº
+8 °ãd<™v©ÔRóÔ}xÊ4÷àƒëÒÀÈâA©.ýÇ4©M3­ ÊÒâ+˜Ø¤v%ƒTb×*Ûù“æºNLZqdK{Ôx  Þ2×Uþ®ò*ÓÂæð;OöHok'ÝGd€Ez˜Oˆ·?Ý`æ;·Œ–Oˬœ©ì³K}Ÿ¹rÂßsz©ê4¡Zø?–—¬y$6{ÀKc?Ä5'ìî°¶”îöõÖeÍ„1&tbOÛYZ"Þøb7qÇ8½h,üÞ‡÷oÞw`x#ÀÎ)樋pó'$8<^(ïó oÕ¥)×ÕÏ‚¹¹úxóîŠGï–î>¬t×™Mõª\gsöM³‰hî² ïÿ¬L¹Bú0Hoå¼· a]#£1;ᨑb[¦9Ðœé-Ùã‰ÈÏQØQyâ^ß›röéŒÎˆ-oû·2z¡ §gÚqZu'¶Âp*Nl¯gt]ðî}Ù°û«ŠGlmÔ¡g‡¨P­RÕöäYsŸŒ•Z'¨Cöq·éè¾—¯Q[Ö
+<lÞ¾ùþYÇg^$>sa"ÂôçÛ6þíúDZ3 ~û$x¤DóXYx¼Ruý4GâºÂòmÍ¥Ü%)NMmð£8”ºå#¯„ä¤ÓèG1W¸6úFý^ùq3šˆ{ÒŠz]U¥±Ûš•Ë²èÄç(ô÷ñé„3PÑvprý!>÷k?½)OÁÜHIFÑ®-—b‰Ê”‹4Óõ_j±‡9} ?Šh$¸¨Ý.Ip‚W»:Né=þ~»¹¿ßb€´æÑOrìÀsà¿×´*sMsÄHsÐb /ºAMêL­¨>,T3îDÖÇœ²³ƒˆûAlfnpÚì ŠÊ™=7éÉõV*ì¶.c.¯ ÙN8£uìªþ>6œVæã4Ù<ÂUè“TוNÒ¥¥.´AYw
+\ûávc–‰$Êшt{»‚ŸÄUFgèkÑá\^¾~{y)Á}#7‹Ÿ
+meåϨvØõ ~ÇŠÏíZ“Xΰâžô…}œ0Hò99ˆ¼ç­ÎZŠíM¥@S×êò[ìÍjäG®R„œµœpÚ ?îVŠÓ{i¸®ÍPŠÉ°æ³È0KgÃ-¿h¨™Xé|ÎàOˆÅYŬŽ³zPŸý›¾&ÆpFi89H(Ô8¹v»ú':¿ÂªyžJW¬ÛzîOÜÊI‘ÛàNZ ÷áýi›ª¤ÞƪÆPNPâZÎXç¢3ÎÅ õeˆ&~XØCÛ©Ó‘£—{Z¹?­Ê³]\~£EÙVˆ)½<gJ¹?­p2:h伋D¬ê¯ÇƒÈ‹<¯­!Ëû”XîO+EK{PBwµâŒÞØéÝŸ“úÒ$óq‹û>¿s"}J‚öÇ­rAU™VŽê8¯púg2w,V3sù( ›#ÜðzÒÐ|”_$Ø‘Ðp{õÏË+ú`Ê/¨nø®¬¹’‰ÌHß ïÇçˆÞ¯~’Ñ:áë O · ÿ{ñ?DŠ†mendstream
+endobj
+758 0 obj
+1576
+endobj
+759 0 obj<</Type/Page/Parent 635 0 R/Contents 760 0 R/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>>>>/Annots 192 0 R>>endobj
+760 0 obj<</Length 761 0 R/Filter/FlateDecode>>stream
+x­WÛnÛF}÷W Ü•‹º[vßd§nSÄIš¨(Šº(VäÊbBî*Ü¥eõë{f/4©(iŠ$ˆx›Ë™3gf?Œhˆ?#širAiyr½<ÜNi4¢åšo]\Îi™Ñ0‡´L{?¨´Úo­Ìh+ŒÙé*3TÖÆÒJ’TbUÈ,!ºÕ•º’”I+òÂV´Ñ;"«)Ód7¹9§J®e…;gË'?,OØ…óC#þõîÇ“ÉE2¤‹ù8¹¤’FãËḫ‚Þs _T.àùïwB~}óî÷·Ë—o^'[ìîùK÷ _öâƒÛ4äÞŸÃÌh’Œa«w?¾˜‡ç~Ü_$S~¾ÜH2²zD> So·º²Èµ¹¢B?heH¨ŒD0ÐÄ=úCIë^øÓôÈl <*ñå˜ḃ1¡@a†Ja,¢]Uz‡À A¢”ø±Få~ËU†ÛDi‘Ke¹h…N…õBžù8(©=¾¸AéßRÙ×ù|U®k|--(ó‘®Ùm®MZ—ð!lŠä*-ê ÜÚåvãXBYnl•¯j÷Á¸ ü:Z¼Xœ#ÅëƒLcêϘZ€raè½(W‚Ƹ›iiHiKzÍü”êr[HdŸóÿÏÑê5=TºÞR)¶[Nf…ì¤T ~¯—þWy,ŸŽg õìrâ”4]6W‘Ôx8r¬znº_UþMÝ÷¸{+)ŠbOŸê±¹ s.RÆõ’OÛ‚™‡¿<b.š­HåýÙ9íuÍ·ê"ëVÉAÛmBn O˜>Ú…fsÀTÒd˜LÂÇÞº,i6K®ZϸYqÉ ·;Sd%t v7]I¦\%©VkÈM%JTÁS4WàBéYƒ:¤ÀÂr N_øŽ[°esJÆî I"Mu­¬IÚYÌæ@yz9GFcüC§­½ú]ÑM½†.ÎÆhN;âËdšÐMôv'ÒM®$-+VÀEðâúüg+èƵášp÷ùð8Œg•BGXd{ 0É´Î`›k-Aã-»–ï×Æ×[Ô°®¬#
+=æYìKìpà3FÚÁó"ÚXºzj `Cíàå'©RyŽ¢DwÍKÌ4XX aUR)Ë•<ÔbWÐÇJ¦¹PÎ30èéVÃÙ~¡êðŒÜìsbƒÚ+}PúüA¶Á!4"Vø€t‹&Ÿ·/n XK I4ZSÒP,™\­Â;ùÀ#h€¡ açœ×Fäü œ·ïì@4QYT©®ÁLÌÃïݨÇÎÕ¬Ña Â¹>‹!:ºÉÌ
+endobj
+761 0 obj
+1878
+endobj
+762 0 obj<</Type/Page/Parent 635 0 R/Contents 763 0 R/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/F8 10 0 R/F9 11 0 R>>>>/Annots 197 0 R>>endobj
+763 0 obj<</Length 764 0 R/Filter/FlateDecode>>stream
+xWkoÛ6ýž_q—vˆ IJå·Óm@Ó.[‡¥Ýð -Ñ6[‰tE)Ž÷ëw.)Ê$0±-‘¼ÏsϽü|S1{ÔQ’Ÿ\ÎN¾Ÿt£É„vÅ]šö£ &cüìóÏBÒ[»4Âc¯^‰{xáV
+‹ß|@Nçj@qL³ÔŽ&cš¥n½K³¤5[Iz1ûxÒ¹‚InO«#ˤ³ÖnR¿N·Hê²ØÒFeeÊ–Tât.’•Ò’´È%a­\‘ Óç§$Ök©S™žÓÆè³’VâNbÉI6¿f9ü–Õt©³G³´%HWX±+‰O¡SÒ†he >U…LJSl#º2É{‘¯3ºoDJg©Y¯·gÐ[ei­Wz¹§î?ýÍÔ' W•½2¦̘ڽa4`‹¾ç÷Ãîÿq½±Gnc«¶îo­’O¦1­‹N*ï:ìòEg®tg!2[o ‘o³®‘Ϋ¹¹“çuÒz!i«ç[”MsDJo)•6)ÔºTH‡KÚ¡äL&™B‚ÏIE2:§KaeŽç×&_W¥,"ouиÀFwãÚN¯˜[“áx¶¥¼b`«z'ËË·ïo¼~³ØSO¥áM 0•òoOM.”Žˆfx
+ÅéB jؤ^ÙZëu„ˆ&f¶ùðƒã¥a<Må4áË?dt÷ã$·ßÓ°!¦aÌö©ÉæsÏB·­Éí çlÃjNÖµâ&Ï™-8uvÅήd!›š Ødª0¦|V×Q°£Õ(¥¶ v^/÷”Ù¨ïA`ÃzŸ,Ð'[.×HS]Ggö <jÔxû†êBÑrö6‰C®–RË‚¡t„‹Earƒß¼÷ûidÖu"FQðžxxÿ„ºôY„JóJ*Ïeª`C¶}
+)‚S¶B}¤,²ð‡©üÀŒ{¤z#
+tš¯\½zV£~<ù©kÊÀwð€©ß6Àݺ:WSŠÁÿ<bõÆCשwCDD½ˆNßë6ÂԾʶ§ôšSÎÖÂ…ëz„šq›¡W¾±¸íêù…G77±Yô*¤û¶ÅIçÆ…ºãQëömÄö
+ÄŽ}ýŒår‰aýY‚*_~!§ n`ð§H4|q×´öZð¥dD#ô{Ã-Áƒ>ÈôGÐ0Ó?+]Ý“ÝbÞÊ
+endobj
+764 0 obj
+1656
+endobj
+765 0 obj<</Type/Page/Parent 635 0 R/Contents 766 0 R/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>>>>>>endobj
+766 0 obj<</Length 767 0 R/Filter/FlateDecode>>stream
+x¥WÛnÛF}÷WL
+aç|ƾ¯¨?%CŽ§Ü¨’LÀ£æÉäz­³#oÑCBtKô Š¥"•(E(½*Í“>¸XôL¢“ RͱڵØߨÐqë+éÙi `̵>:€_œSQ…’–šPoíÚ‘ƒä¶šCÀs;“ç´R&'³â¬‘¤±Êï‰!ìømAÆk„o‘™p¤G+7¸Û WåÇ@A é
+•nŒÕTz®TƒZ" ßk
+k@ãÏd{Ò_Á¿®[ˆ4:ü0 ÿ¸
+gÃ2
+b„Q
+m«Hã†&\ÃF…u÷±ªÐ´¬J(›,+$ÝèôQê¹t_ét* AdS½‚&è¶ÖYÝî¤%§D3ŽDNU€ÍÆi˧ ÈUþv–xú9N ÖýG:b þèf­ú ‚øŸ1l¥SCHCîxÿ »6xõÌèHEV;•£³(©¥C[d54äq@Ô4Ƚ«b[ Õv›ïŸæQ_íø:ˆ‡§CÝæu¶8èßÏO0.i4&×4¾™àó¿<ðºÓutuƒas<__'̦ô£wË\Ü2zï½óÒ¶/ï† Öxe™¡Æ¦y•aÐÙ«3ü‡ K¸õ´üqÞÒYÛŽ˜^ôÊý‚Þ0¢¶ õ;ý´Ó«8®8ácÐj»Õ6ÓYB÷^ëwwl¹­ÎEq(¸'ÜÆ$؇8ý†(vΞ•u;@î2µe{8
+•AÜh˜ìâÚ¯°0äû„\T7™VŒ†Mrå8CvVÃúº™SOf»‹H7ËU¬38m…£2ÌܸžÁZBú9µÛ¸¼]g‹-í²Þ¬Ü<"%I7ðÒÆ×8.…ð¬ùRiú›7£ÙýTÇÚ°³ìŒÖ2¬1¹Oÿfrl¯,”:k/G[d‚/´Nh÷té-kWTù…d‚Æ/ ^å¢6MDÐ-æW¹IQ^#eÆòÄb€0YÙÅŽu,3„/>K&ŽÑZíßÒN30^Z#GoÐdñŸ6ÂìÐ ‹¥‚Ó£ë%§´Â)™tlÊ sÞ¬²Ž*¶P]ôt²N`ÒÊ(Ãn©¡ö®(lʺèåÙÇé+\?Úý>ÞMë¥låòÜí ýIÊËCÇ«×7\4²ºdD­"‡·fÑbÊôíbñiöáÃ|±ø5òü@}¶'Ôû™.;;ZËÀ}å¡ï ÀËr½± ºX‚·èEJÔºö®Úžiìß,~SàÎ$í +_ˆÌëdÌŠ`›W™Eo©22™VÀ’oÊŠÀ@åP­5PˈXf $„è• ®ÐØ
+endobj
+767 0 obj
+1534
endobj
-996 0 obj<</Type/Page/Parent 794 0 R/Contents 997 0 R/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/F8 10 0 R/F9 11 0 R>>>>/Annots 233 0 R>>endobj
-997 0 obj<</Length 998 0 R/Filter/FlateDecode>>stream
-x¥WmoÛ6þž_qK;Ä"Ù²ÇI·I»l–vk\ Ã2 ´ÄØl%Ò¥8Þ¯ßs¤(+NÒ~Š¡HÞësÏ?ï%4À¿„Ž‡4šPZìÏö~œí â锶?å‹MŽã!§Çøs4Š'TJºÁQl &ñ´ÙI†øàv
-›ßþ@NÿêšÝ@ídzL³Ìíh–öJcªgôböq¯qԜꭄµëŒ¢¼Ù…B¤K¥å?ZrçÎs¿·š¢á$CWo¶”œ`F¯/«´ïµÜ¿Ö#©«rCk•ç”+[Q…ÛZbµ„½jI‚öŸï“X­¤ÎdvHk£*ZŠ[‰-'Ù”ü™åðWV3 (!œ°I®±c—¿Bg¤ ÑÒ@|¦J™V¦ÜÄtaJ’w¢Xå,´kDF™Y­6Ð[çY£W{_‚—u_õ7WŸ$\Uö4È8á|% |¾ç§w§Gƒ#üOšƒCr{mfTúi›A³{ÚÏämŸ]>íÏ•î߈Ü6 ‹X×ÄGçlnnåa“´áƒäßSî÷(šæˆ”ÞP&mZªU¥—´„’3™æ
- >$ËøÎ…•Ö¯L±ª+YÆÞù ±ÀÖ½x[½bnMŽëù†Šˆ ¬ê­¬Îß¼»òúÍMG=U†}4€rÆ >ž™B(Í°
-ê­YÃdák#5e)íÊèLé}Ðꎚk@¥…ŸRSZJQq•°£ZÞUd+¹"eÙ ¿InÏÛî#i;ñ}ŸBJ®0VÊ_×(¤è“6kMøX)‘S[1ε֪Pœ.Ô0¡Mf´¤Ú6òX¯ãÄÀe ÚûŸõ§'ÀiA“ Ñ/rºbÝÒž;ï¸/°Ú€Æ'‡ï-ûÙbîYèº7½~áœm‰ÓÉr¶PKMQ0[pêì’]ÊR¶5H¶ÍÔ£ìÚ*¥HPT|cƒþÖ¬÷É}¤H8×HSSGö^y4¨ÿæ55…¢å:œm ©eÉPÚÁÅMi
-'ÿƒáþ~™M‡Ì$ãI<¼§žé~A]zŽ,B¥ù%U2S°!ß<
-½þs(åC¢©Ë†C9·uÎH™£sB…p1êð¹B—¯3øÁ:8ÊÝû>²UÖbÐõ|°å KºÀ™ ’Ò\ºBî\¢ìŽ«…,æ²´á—Ü`9®dê
-ZsQ.Ð䢔øtƒøÃRð±•BŠà”­d) #þ4µ˜qwT¯E‰Nó«WÏj4<I€IϾƒ'
-^€\DôŒ¾‹ã¸”<—2U¢ˆW¢ÿaR¶Øùáá•ÐÓ÷Ô¯mÙ·<ó3‰ñ~”Qû hA «ÈÒö]@Ñ%}[Ð0%MŸ`¤ió6HðLå-ž” _]žƒ›Kó/*zmÒš‡}‡L6=ò·"­÷?l|<FÔXyorÌ¢QŠ¿ïýƧ™pendstream
-endobj
-998 0 obj
-1687
-endobj
-999 0 obj<</Type/Page/Parent 794 0 R/Contents 1000 0 R/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>>>>>>endobj
-1000 0 obj<</Length 1001 0 R/Filter/FlateDecode>>stream
-x¥WÛnÛF}÷WL
-4MaA½¬È•´1¹«ì’Vô÷=3KÊ êdr9—3çÌ ¿œ è
-ßš i4¦´8y7?¹¼Cƒkš¯pg|ƒ]%WWW4O{ƒarŒúÝkìšÊ¦in´-©tòß+”±çóÏ°sMƒA´ÓN`§7Çñ­w©Î*¯iå<}® )JÌdb†ž”7:ÐΔ±þ¤}0Î’[Ñ'c3· It5®]!‹þpœpÔ½ú |<•Ö§ú“äÙáÌb8žÐq´|ïÙÆF[ñ\íIç:-§ÊqËõç°Å /šÐ8Õb‹óœ()K*M]¨”Íh«BØ9Ÿ±ï+êFÉã)7ª$ð¨y2¹^ëìÈ[ôÝ=¨b©HeJJ¯Jó¤.=“èä‚Ts¬v-ö7*tÜzçJzvsm£¤àçTT¡¤¥&Ô[{„¶Áß_ä ¹­æðÜÎä9­”Éɬ8k$i¬ò{b;~Dñá[d&©ÁäÊ î6ÃÆUyÆ1PÐB:ÀnV+`P#®»\jT‰ÐùÎå=¸/ íÑ¥.ÓKy^JòLÞgë÷KÐiåM¹'òZgC"†ú¨`Ã:Ž?è 4}Ô{¦ê3’/TK1«~,Á[ê÷[A’gî Ó²V['¡Cµ—B¥c5•ž+Õ –¨Ç÷@¥Z€3EBŒ‹³}„Û_åÈØuËUm39„ÂÐ8Ç3ÙžôWð¯+Ä"?Ì#è?®ÂYÄð…
-I7:}”z.ÝW:
-hÙB¯  º­uVw‡;icÉ)ÑŒã‘S`³qÚò)(r•¿%…~Ž»Áᤃuÿ‘ŽØ‚ÿ»àÁ,ºY«þLj þg [éÔRÄ;Þÿ® ^=3:R`‘ÕNeÄè,JjéÐYE y5 rïªØÖBµÝæûç†yÔW;¾âáéP·y-Îú÷óÌK]“1]ßLðyˆ_xÝñ:ººÁ°é Ø× Ó©@'ýèÝ2×÷…ŒÞ{ï¼ôíËû£i'“ubY¦¨±i^etöê ÿáCC.E=.\‚·tÖ¶#¦½r¿…² 8 ‡(îCGýNCí4+Ž+Žø´ÚnµÍt–н×úÝÃ[nËsÑc@*î ·1
-ö¡N¿!Š³geÝ»ŒmY€à1ã…—±y·¤2û ƒÎCØY¢V28µöª8ˆ°Ph³8_OgS̤BeP7z#Fû#¦¸ö+l ù>¡WÕM¦£C§a“\9ÎÕ°¾nÕ“Ùî"ÒÍvÕcë N[ᨠC7îg°–П¾ÁDNí6.¯CäÙbK¼ì„§7‹#7HIÒ ¼µñ5ŽK!<k¾TšþæÕhvG?Õ±6ìl;£µLkŒîÓ` Å; ¥ÎZàÄÛÃÑ™à ½â=FzËÞe~!™ óK‡W¹h£MQ´AÏ„ùUnRT…÷H²<² ŒVv±c!Ëá‹Ï’‰s´–û·´ÓLŒ—öÈÑ4Ù|Á§0;4Èb«àtãìzÉ)­°DJ¦›2èœW«¬ƒc§Š-T=¬X€´2Ê°\jh…½+
-…².z@yöqú
-×–¿wÓz+[¹<w;(E‚òöÐñêuÁM¬.YÑ_«Èám§Y´˜2}»X|š}ø0_,~<?PŸí õ~¦ËÎ’Ö2p_yèÀC…ÇKðǶ\¯,h….–à-z‘µ®½«¶g@ 8‹ŸÅ¸3I{ÂŽÁ"ó:³"Âæ]fÑ[ªŒL¦°ä›²cEð
-P`;Tk Tã6"–( !úCe‚+4VÀ­sì Œ›º Fƒd€×³7L®‡Û?ÞÝò´ø ÑK+¬7¥,<üT0žàp2”Wžy‡»ž\7oJ㶅áö×É¿-–t°endstream
-endobj
-1001 0 obj
-1535
-endobj
-1002 0 obj<</Type/Page/Parent 794 0 R/Contents 1003 0 R/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/Fc 12 0 R>>>>>>endobj
-1003 0 obj<</Length 1004 0 R/Filter/FlateDecode>>stream
-xW]OÛJ}çWŒªVM¥à|@àå
-
-ôr«Rñ‚T­íM²Åö¦»kBþý=³»®[Z馠؞9sΙñ÷ ñoDÓ1íM(+wNf;g³arp@Ï?ÌW“!Œ’1íß'‡4'd$Íù‰a2D˜íÜ>8ߧшfs;9˜Ò,÷7 i–õ”#ʵ´TiG¥pNZ/…ë#`ª5~‹*'g6$BU ½›}ÛœObÄ!íŽ'É>BöfKIvc,)•WèmtMº¢ûÞ‡!>£Ã“ûw >!LÃìNQòÉ{÷ãÉ4žÑdÍ׶§\Ð7­*‰”p\®KäD¶Î2ií¼.Š ¥µ#1ç2êÕˆ\U "§IP%×øöQ«žû·¢Le:—tA éøKÎm•ö
-'wW7Ÿ>Þ\}¹Np¸©éBœ²¥¨2OˆÎQŒ|åªýNÜr#KýˆâÑ¥¹*¤gQø¾9Õ–iÞ=CÔ=u*ÜKÊŒDZ644’8øÊxN Þ®Åjؤ"{ðG̵qËN:©tk ›Ö['ÃdÚ§ÙåÇÀn$ù÷Ùñ)¥FTÙ2°á¾ÇŠ02Óe)«\æà-
-%+Gs£Ë†˜-¢Ä›X F²,þ ÎRdKhŒ¬-D’eºæà8Ù-‘%*]Õ,©Ð6ól è3èÈâ.FB
-åýoß1«/¼8€'%m¥HQ{AzMMê¿Ï½ÓNüåB^%tÛ{ Ž¯®ytÅÕêi&j 1¥`8q}úÁ#³ÌGORN
-~E¶P;.@¨
-‚~”ÐŒz®Ù+ÛCiž©—¢ª½øcæ6
-mV˜Ò¥° ggB  ø­«_ÎÐêࡹsX”°WGT6:Øabcˆó´ieáÇ—£s¥áìßxpô¼8Ëx r6>ÞNBþ§a£ñ†/èr¶?¸òê²*ÒUÎá÷±µF‘jì<å¦S]ÊT2¹reÙŽ‚Àç?,^˼´{í&“°áAé¿´@A×ÇŸ1„
-8 <±^°tBEㄧ-ON<ì¯Àbçê ÷á¾:ÂÕ+Àl:Ø 6]ò`bçÛê
-EÅÉCv‰¦`ß©8y˜JY¦ì‘ž–Ã31¢où)‡eD…^‘ÎaÒžoUXÌx5IÐœ#"¦rž‚Ñ%ÿ•dGøëkÄö¾7žÜ¿ãâèËå§Ë«»K:»¹¹ºñù‚LŽ:ç¼aÓ.ÇÃÊIÉh¹Êò„‹à§â¡0[V1Çœ·—©(º]l(á”pËvëô
-6¾6SB›‡}VÐ\-šÒk¦]¯9¥“5?äŒ.h^¦U¸Ü¬®-¯ŠÆS&ùÀòRßÖP`¶Kð!¿°F¿/2?±jÐú{­xqŽ&ÀJšR¹Äúðùkaöø«ÇûZÀ³
-endobj
-1004 0 obj
+768 0 obj<</Type/Page/Parent 635 0 R/Contents 769 0 R/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/Fc 12 0 R>>>>>>endobj
+769 0 obj<</Length 770 0 R/Filter/FlateDecode>>stream
+xW]OÛJ}çWŒªVM¥à|&—+(Л[¸Š¤jmoÛ›î® ù÷÷Ìî:qÝÒJ7­
+Y¢ÒuÅ‘Ú¦÷¶€>ƒŽœ!îbTð($‘¡¼ÿ­ã{fõ̉èpòšPÒNŠ´ç¥WP§þûÜ[½áÄ_.äUD÷°½·àøF«rù—ÓH[\ž&¢2S €7ç2+ñÄ|ð¤Ì
+
+)øêÄ–oÛIðŸ7Šd;r¸
+>†%Õ“ÿ….±S¤Ö˜Mêm ƒQZ ù
+4ÚšÂ1l5W}“1ešÁ‡ îÎ"CJ€Ð8Ž*›å™ÝvÈcûÄ}q\S}D)
+éìßÕ´»’ölv}Gîm lóíë·çt¶Æ¬ àï‘—sÃajKøÊ¿&¶À9²Fxv˜m½FXÅ
+Ñ{Ò&½
+ŸP5hý½Êxq&ÀZê"³‘q àþëaŽø«ÆûFÀ³
+ÂÀZÍöÿÃÛ8ÆM­wö¦ÁÑ àE÷Ø·óîôóÙ)Ýhõ7ós•TØç½™2Eã n?œ Ýûç4EGýƒ…´žÉü
+endobj
+770 0 obj
1802
endobj
-1005 0 obj<</Type/Page/Parent 794 0 R/Contents 1006 0 R/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>>>>/Annots 236 0 R>>endobj
-1006 0 obj<</Length 1007 0 R/Filter/FlateDecode>>stream
-xXMsÛ6½ûWìMJÇ¢õ-+—Œ“8§ušÆJ3í𑄘T‚´¬ß·
-VÃg¬Ž'Ñ,\ ž±:YœEÅ 0X'ØŠ-Õ°u‘¹kxÁ¹jˆæY×P©>O—£CëÀyƒ>‰'¡2±Î@÷Âät¯’ÂX³)#>0p Æs”8ô^¢*~¬aú¤©bΊŒRYŠ}Ég®ÞÍk²£ÄÚ£_˜hbmª2ŒËUÌ‘naȯüé¤>=XDר9¸Çó…Kü©Žx­µ½2”€,àˆ,a«Þ ú¹¢ëë21z£¶ÑÞdÞIS}:‚¼yeKªÀxG7ÐûAO\UŒfÞemuÖX…1vÉgÙ5
+771 0 obj<</Type/Page/Parent 635 0 R/Contents 772 0 R/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>>>>/Annots 200 0 R>>endobj
+772 0 obj<</Length 773 0 R/Filter/FlateDecode>>stream
+xXMsÛ6½ûWìMJÇ¢õ-+—Œ“8§ušÆJ3í𑄘T‚´¬ß·
+VÃg¬Ž'Ñ,\ ž±:YœEÅ 0X'ØŠ-Õ°u‘¹kxÁ¹jˆæY×P©>O—£CëÀyƒ>‰'¡2±ÎÀöÂät¯’ÂX³)#>0p ÆsT8ô^¢(~¬aú¤©bΊŒRYŠ}Ég®ÞÍk²£ÂÚ£_˜hbmª2ŒËUÌ‘naȯüé¤>=XD×(9¸Çó…Kü©Žx­µ½2”€,àˆ,a«Þ ú¹¢ëë21z£¶ÑÞdÞIS}:‚¼yeKªÀxG7ÐûAO\UŒfÞemuÖX…1vÉgÙ5
Æ¢¼Ql¼¡ÒIV¥2¥ƒ*w\Gµ£5`ñ6ìúÚ”¼á‹)mé´¡ã…·ÚqBPÒâ<T‚œF­›"Ø‹lbÄc+UúÜ9‡!3ªÉ[¯ ¨Û·a¼«
FqI"+!Ûƒ±¡ßrFè¡ií0 BQ×Ì€¨ ^wî~åºä«T–ñeˆ
wõÜÛϽÐb+‹žËYÏ
-ÔüÒë¿O•h n<L®Ss~ª#¼¼×æpI»0,‡ÙYl®°ü$e{n˜èàÔ ûU7­X õAo;f!%–ßýË$Ï=\i”øaJËçÊ:ç(O7ay¡Â633²îÖv…óå­Y`]·I߆ÂÙþðZÊZÀ1ƒ×SülX¯5UŽ¥öý4LdÖÿ4w‹I§¤ß”<Ô/Wïþ)¢ëz¨ù7ºë™áy¸¹}ÃoX_1kÐ[“Tü6ÞNãƒÑ|ÀÁbìnøïþ0]L››ÅI€æ_/þQ@÷Uendstream
+ÔüÒë¿O•h n<L®Ss~ª#¼¼×æpI»0,‡ÙYl®°ü$e{n˜èàÔ ûU7­X õAo;f!%–ßýË$Ï=\i”øaJËçÊ:ç(O7ay¡Â633²îÖv…óå­Y`]·I߆ÂÙþðZÊZÀ1ƒ×SülX¯5UŽ¥öý4LdÖÿ4w‹I§¤ß”<Ô/Wïþ)¢ëz¨ù7ºë™áy¸¹}ÃoX_1kÐ[“Tü6ÞNãƒÑ|ÀÁbìnø¯þ0]L›÷šéŒ9€÷å_/þ“Ë÷endstream
endobj
-1007 0 obj
+773 0 obj
1793
endobj
-1008 0 obj<</Type/Page/Parent 794 0 R/Contents 1009 0 R/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/Fc 12 0 R>>>>/Annots 245 0 R>>endobj
-1009 0 obj<</Length 1010 0 R/Filter/FlateDecode>>stream
-x•XÛnÛH}÷WÔ›@¢DI–ìyYäbÏ°“ÝH™Ì
- nKõ0[®dH»òíñü¸F)?纟­vþ$â&`£˜ãÜq³F%sd­¥ØÆ;&hÓï¶êrìŽc²¹1Ühä²m, ÏùÐŒ+td’g:pgi ^)ÕO:Ũz\6h
-ž+«þÖ5„ 
-L<z™‹Í;§m ľxâûà¡<vÈ,út
-VèR­ƒw5
-ÜVð A7P•ró…-ùQä4¿d¹; ¯j·d¹VëDÜ,¼î‰8Q…ŠM—›$iTä×Üüq€üœÏˆöØèP, ÌB+ŽYó68ö¨öNR‘󈦬ˆÏŸ>ÉMnt¸¹¿ùREõdáSÖ ¨ÎNèÆDH÷67ï2=ª€
-_—°íÁðc 7.h“ÁÑ'7¶ÑX5T¨-¸è¨
-,!J¯‹Vã%–µ Ûár±¢hÒÂ¥^u‘&úH¿â: æ‹ëQ£Nù<âšI7?/Gï‰xñLßφÎ
-‡÷ ¶g¬Î** ÿL†“l}ð­¥ãé`Ä0á1Fø°ô»­zeÅçÍ‘þ:Ãp?Üó9¼éÀéÀŸvûü‘N8£È_Blž€¸6®ßÞ¿{ Ýe¿c p~?9 r¤ãdŽE¸š 6þÊÙu±ZàÄ#¯DªcAüëâ¿Ycendstream
-endobj
-1010 0 obj
+774 0 obj<</Type/Page/Parent 635 0 R/Contents 775 0 R/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/Fc 12 0 R>>>>/Annots 209 0 R>>endobj
+775 0 obj<</Length 776 0 R/Filter/FlateDecode>>stream
+x•XÛrÛÈ}×Wôé*$Hš’ö%å‹”¸J²“^ïVée ȱ€.f ZµÉ¿çt HHI%å2%âÒ×Ó§Ï苘¦øÓåŒæKJŠ‹÷ë‹›õÅ4šâ:Äüñõ¯³ømtMË«e4¥‚Ë+ü¬¿å´â·&· ŠcZglhyuIëT,Li ?ä&y¤.5G©;ØÜ©”ÂN“*“yÒ)e&×ôfý£ï¼ÜÒ0 û_&|F…IJç]¢Ä“~ÉÍfr¿º»ýtw³š|¾ùíÛ*ºùíæܤCSϖѱ ×ðýÝXÄâéóšÈçI—Þ8K.“Èß¼.é^YµÅÏÌ•D]¡ŒõR6¥ÁJ—x¥}‘žzR&W›\s
+äÐß]Ï÷”(KŸh«Ã_8ú+܆
+·ƒ«‡ÿ…²Ïä]U&Ús+ŒEé ¸3Çêâªôˆo?…¾äÆn)7>ø}½ý0ðÒ¥Ô%U¡mIiÏ£»ÆÆ0 ¥‰&ìĸWÅFQ
+‹¥ÙT@â` ¾Ñ÷gÚ:—’þ¹Ï¾+á"I«K…îÞ¿Ø÷Æ}•ìHùžßM ì!æ¨.ɲŸ#H¥Œ\Ï‘¥Fm­óMçr’ra+_•ÞT[ <˜RíK‡RÖÕ8H™ënd@/$4¬h:”4áŒ/Ñ߶T³å¥Ìh×A¾=ž_Ö(å«ÛéÙhN"næ)J9Î-7 ‘aR
+OÆÓJŠm‚×y†6ýîª.7Œê8%·ç"÷"fƒ
+v@/&§‹]€q Áž©¸FÅ•ÊpX“Û· ,†´Mo{hR–«­d k“ç(I’Wé‹¡°žÕ«鱪4h
+ú' ÿp¤“Û#wCA¥Ã‡ÙÛioRqëHi(U’ °Æw4™üiuØçÉ*„Š€ÂÂûWcá?[‡’˜]M£˜fó ¡ 9ôbûí58›ÏdqtÊç•Å©-k¨ôL’%û´*ö< øo‚ˆvAdãápˆ¿¼\¹ŠŽú¶Õ;CÐÅ
+_Í6mrk÷ó‰ŠoâƒaХߙ=¯$L¿/›Å×°âJÔÍòGr`!Š¼IVb
+ôÈÛDZÛ‰"€
+\¨ËL%, x­Æ'•«<Æ4Õ¼Ÿ™Y;x×ìŒ}ó2ifÉ^ŠÎ‚å$˜“Žpø<©­{4——X‰å05 3w ¤)üðRaj‚Ui‚ErD
+µÕKFˆ2è}«ñ2ÇÚ…íp¹XQ4iáR¯ºH}¤_qFóÅõ¨Q§|ñͤ›Ÿ—#‚÷D¼x¦ïgMg…Ã{ Û3Vg•¦ÀA¶>÷ÖÒñt°Nb˜ð#|XúÝU=²â­FóE¤¿Î0ÜÏ÷| o:p:ð§Ý>¤…Î(òLJ›'ÆßÞ
+Wïîß¿ƒîr?08¾Ÿœ9Òq 2Ç"¼œ 6þ‡£ëâr<½X² ì‡\ü‡,b¯endstream
+endobj
+776 0 obj
2019
endobj
-1011 0 obj<</Type/Page/Parent 794 0 R/Contents 1012 0 R/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/Fc 12 0 R>>>>/Annots 262 0 R>>endobj
-1012 0 obj<</Length 1013 0 R/Filter/FlateDecode>>stream
-xÕXMoãF½ûWT•À¢DÊÖG.mÅcÇ3³#ƒ
-uV+š‰b)ÎÜ^Gé5u(µ¶ú©×3¼2Pzíʼ={‚×ôER*€HAE¦5”§”B;¼wœå}•·ëÝ [ žÊ™«ª
-
-ÖìAè $™Ô¨=W^)­á=×nÆcƤ<éžäÛpƒl¢0
-&!§1²ô'袿z‰÷QbÝ~fw™‰ýäáx}{3;˜Ž‡gvÃæÅЋ³•é®n'Á!ø_o¸ÀkDád 9ƒÁd{õRádŒuû@Ò§ªpŽ—Ýíoeöøµ6aužMA¼ ƒX½ÿä÷qÞ+m‚Ïß”DÔcü†ãsGºÁd‚¦ø«“_‘ífþÉ]NAåì˜gwWd*7’ðœµZ¹AŒÿA‘ÅZµBJH¡Hº—èu{ú IíFìÁ Ó¯HÊ[ZÃË°í4Ÿ«ÊHf™3?s÷:ÿ¢ŒEã ÈBßú!ƒØ_=«Ìy8ˆŽZïÏ\Ae],Qµ­„iÉS2¡ƒSôoòê5|¼QÙÎvoÓN5XÖ¤qãwÿ¥®=÷/wOùÚ\´6««JégòÅŽñ/ŸkÄúÅLý[-ô2Äó"š@&, ÛÅ
-endobj
-1013 0 obj
-1871
-endobj
-1014 0 obj<</Type/Page/Parent 794 0 R/Contents 1015 0 R/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/Fc 12 0 R>>>>/Annots 267 0 R>>endobj
-1015 0 obj<</Length 1016 0 R/Filter/FlateDecode>>stream
-x¥X]sÛº}÷¯Ø>YéH´$ȹ/wœÏúÁŽo¬ÛL§îHBbÐA+ê¯ïÙiɬÛÉÌLñÀâìÙ³üãhFSü™ÑbN§TÔGï–G'ŸÎh6£åŠï^\.hYÒ4›N§´,FWv«v ]ë:×âZEü£©ÔOÚú © éÉÛÖEË1?ÞÉMr>ÒF™’”+Óm‡aáÍòûÑ”&³ÓlŽÅFU«‚âÁ=m‚/ÛB“ÂÀMÑZh¥Ul±
-Ö~ù šZgtåvĿȧS<ǹn"U­nšc^nr°ƒÈÖÆUTû€ ø“OEÃhÌ/²3Žía~>í÷(áéäômvÁ;xjí¢ñŽ¶Œ6Øð…_Q£ê\ÑηGÛðŠ¼º¼GŒžŠ|¯Ù5Q×d"níD­+uÈ蘩YûÖ–ŒS®r»Ãž±QÎ’dõ€¤FNÃ!`ñ@Mg…w+Z«Ç £Õ* ‚ã7i(Gÿ¬,±ÿÂô¢V+ÌKwÞSÓn6>Ä?ܵ#U–FPCÖ9þ·1‰š|òYÒ½ ødÑû¿ßS¶°PE 4µ-ö4ÜO±ÖÅ#&1‘|ûjÄ= ÿGª{&,HÜÕêQ'Tÿ
-Â7)ÏÅ¢ ;ãvÃ¥ÚD΄6žAZ¼HrÍU+!¨¤2š×öñ“O Á7@Ñ7™FˆÕk2W¤&•!ô‹s‚x„ 4Mj}­6í &ƒÜ”œ½Ánúq9„)éÆÄÅÒ×i®€IÔÅÚ™BÙŒèFAó6Úƒ¤PíOÀÙI4Hƒ
-Í›"˜œ5u°KáUƒÓ#3±™Ê9¿K€rì\bÐ0ÝóŠâÖ#S°â^ú²ŠÚñ‡ÛøZóì[c-øÇzÞqS6Ä)ä¡,·¢gˆ4×1"}¥V|Ü
-©¸x˜>¯eü|ž]þ9¿1gu­MµŽÐ¾Â¶¥î„ÿ¢ë #éHÊrû¦9B•W"¬ p0Øb’ØGÞ‚„Ü'€B5T· þŸOÝË0zé+|h4RÂøskAÂx‘ÌÓη՚VqÒù BÔ? o\hH­sÔIÁkpüd<ŒîÀ}ƒ.óð†®SU¯VUÏšDNÇš™šöÈVœå0Ðݸ‘qTr½1&£üN>¼²Ù£$XÝæÿš½¿ºp³­¶à~‚ÿ°Yÿäv:´…{X&èUk¡©ÜªU!ž
-ÍT‡Þábã<NMÒ®ej2µ¶]J-‹hkbƱ}\±ãÛK3þõõóÑÅivN§36‚5ÍÎÏXº²tϾút¶›¸÷ËŸ%sÂ…—†ŠFë7¿œœˆBg’ø̇dõž_–8øeö Öè7bnR Ê¢¹ÔFê›%›tû·Êç½ZÝ'“–îöæu$òûràËqF9/.‹ÏA[å1@m~ºÈ¦t:e'_Óüü2[tWH{œÏ3<<Ó¿G,£/((Ð"ѶÐ)xêA6BÐ/ŸõXMfsÎÃ3me55ä^ {JM¯‘6 ùtÄ'¢p×úÞìôhÁJ]‘i¥rPP"ÙŸa`f‘ö]­³üC,3LzÁ+@‡ñ(?î‹k“e4µCû
-endobj
-1016 0 obj
-2245
+777 0 obj<</Type/Page/Parent 635 0 R/Contents 778 0 R/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/Fc 12 0 R>>>>/Annots 226 0 R>>endobj
+778 0 obj<</Length 779 0 R/Filter/FlateDecode>>stream
+xÕXMoã6½çWLEÜ"–-ÙñG/E7Û ›ÝíÚÅ¢€/´DÛj$QKRqréoïRòW’nºè¡E€À²¨!gæ½yOþ|R! #ê (ÎO.g'ë>…!Í–üÕ`4¤YBÝ ÛíÒ,nÝ©ME–=Ò£ªh“fR&d¥…±¸C§ï¤Ý(}G·
+‹•¦™R™!Q$t±’…=%RÙµ¤w3šJ}/u@XD‰Â·©¡ïfœ`ëv4úؼõF!úÔ
+m©¬M‹•ÁÇ+UX­2ú
+™áššy•¾OcÉ«.’ÄEì\ÇuZmd‡d’Ö<:ïÖ÷š”q«ö‚ˆoOe&cëNúåœ8=Š³4¾ãìNßÿr|å¶W.GØÖ©.èAÂ_þ¦0•äúJ‹Dm̮ԺÛ>^Mˆ6kYP©U^Z™ü“ÛÑù®¼[ª´ð;£S9Ê´L3ôȬU•%$Rc±{]6ÀÒ°EßNŸÎ~ºýøþýìÛù|úh¬Ì{Ñ|^¸ óù÷Á÷ ™n[Œ§â/ÛÝ]?MµHR–*b[¿Ÿ0´‘Yvv¼k)4êdæó£Ð(I¯)öïêXH@ÍýH“·oO -z~8­ïs¶hï4¥ˆï¤%Jª¼<sìð;móŽEi+-ŸÁ÷¡‚ܤt"õ> ¿|•­ãÊ-
+nõ'pLµ©*Îv,F/4ÊLfÓ€ÿ¸ž ¿kV/«Ý´‡&ìÿ:±ëd˜ÎžÍÿK:ïõø€ÓRÿ;œ~§6 Aùè:îy¼Àv®3›_Á^pØñš§jÙÏ•Ûf˜U¥Ôyj 0å1äpžH™m#J ·R§ÂJÇZˆš&“ZÐïúF"ÉÓJƒ8÷’tºZ[³Ð3Z¨¦Ÿ®
+pˆéþ„¥P¸F"ëñÇ”Üáñƒ‹Ñ,aâ!RDsB*X>‰¶unæ7½še6oÍçîÌnNº°˜ßñ|\K- CY–X(Ó˜2£ ¤Ý®÷†%iëzbו˜ÒåѾl ÜA²˜ƒ¹›3\§5
+uVKšŠ|!ÎÜ^GéµhmmùC§cxe ôÊ•y{ ÷¯ 蓤µ
+íðþÍq–¯ô=\TÞ®s=h4x"ïe¦Êøów¿ÔBC㊿ߺ:Ÿœ?ŒÁ¡@âà" Ò¨Õ"“y@7K2ê á‚îicóË®…· ‰?4™Ûà„!b=0^ãâ^0y ‚¦õ4§±²–n¥ÖìiMšWxÀô¸œ\ÑB¢Æ)Š+ÜQŽa«ÿ‹
+$ ûAX_ÕHxÚS ":¥Ý!¢nóf³ Ì]Z–HßH«‡ŽÉmͪ`móìE
+›àóW%uG¿á¨ïH×Ñõl£ó#²]Ï>ø¡Ë)¨Œóôö’L)ãZž²¶EK7ˆñ?ÈÓX+£–H )ÔIw½êpO¿"©Ýˆ=xaú ByC+x²æsUÉ,sæG.ã^矕±h4ùÂ^è[?`û«'Uƒ9{ÑQë½Sà™+¨¨òª¶•0-yJ&tpª€ÞàM^½„W*ÛÙîmÚ©Ëš4nüî¿ÔÕ¢ç^  ðÅî)_›óF¦UY*ýD¾Ø1þísµX?›©ßb«…^†x^DcèÁ˜%d;ï¡¢î¢.8Ê<îÐë€ü\!=gXÝ^ÜdÑ«éìÝL°¿)j㜰ghÛbžáP¶è†Ç¼²¡fZºÍùwÈ­ãæîµ™]¢ŠS‹÷whÃî˜b¡*ëØæâ´¨$1
+‚S–"¯ïÀÔqå…úshæ…ß W’ƒ¨Â™$Žå¤2“Âà»…ûn“é[Ui hGãë
+endobj
+779 0 obj
+1869
endobj
-1017 0 obj<</Type/Page/Parent 794 0 R/Contents 1018 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>>>>>endobj
-1018 0 obj<</Length 1019 0 R/Filter/FlateDecode>>stream
-xW]oÛ¸}ϯ˜‡nˆÕØqídw±@Ò6…M›[»·}È -Q1ITI*©ÿý=3¤lGÍbqoƒ¶±)qfÎœ3ßÆtŠŸ1Í't6£¼>ºZ½ºžÒxL«'³ó9­
-:ÍNOOi•/¼ï´'§+tAÁRØhò¦¹¯ô¨²÷¶¡F‡'먶…®H9M…ñyç=ž7 ž7ž¼Îƒ±MF´TõZ‘ïÚֺੰµ2ͯ«oG§4ŸeX?–{ýÉîæhÇçδ_«¦ ÎkG­³¥©à^iÝ,é‹i
-û?²K÷Îv­—çN/¾¾ºy7°˜WF7pçicò =™ª¢µ–PK‹PÈ–ÏãH¯OfÙ”þ²Ñ ÌÐòæŠâU¹JÑá>¿—
-¤(• ”Çn œ’Ÿ¦`åƒI½L‚Ï m0æ'–yæM2‚w®—Ô¨ZÓÛ7—‹Œó? "5ÄwÊy¥¶»j‘|Î7Œ‹e!xØ‚¿z
-g@ÍJöNØ:°nŒÂ²’¥ð"X¯Qw¾nf'#4¼cûâöÍ/±âà®Xãe¶qÑÞí¾5Mön÷‘ ÝŽ>qn¾<€úŸÒ³Ä÷(;œAŽ( º±ÏÄÊø/Q¤+vÁŸ;ûgÇžã©÷Œ”š¥ª•Ë¹Wq3’Î-_›2‘¹´ ex¹­‡x¢ÔÐ'Ï 1¶ø¬þ¡óŽÇ‡µT©$+ÙË2  ±!tâ.Ï}"•;o‡xp¿ØÃÑ'eº‡ãïè¡,$Šsô^‡ESÚ¾÷Œ‡{|ƒjI÷BŽ6Ò
-´ýä’ÑÒ4yl‡¸?
-´7ý7Ž ¿¸U#VéÀ`Ý¡„×\VRw7{ãâ f¦‹¯»Vróy¹b?L±Ó3_@æÀPaP70$l÷è÷P¿Þ£ÿz’ÿ³¸w”ßÃùSŠ'ÅÑ%8„‰je»p2p²ïš¾Õyj’ý‡¦<WhÉ¢è Ž©`“Ñ5t ¨º­ô‰Ô³È‡»»SÊÝ]¶óƒ%›Œ±ÌÚÖ<‹z„éqn1|-ú"¤±Ç°gðlaëO•æ%¼p¹ê%* 5À¯X˜vúFÀ}5Ö‚7?\/Þg·ÿŠJmm…ɉ ú/FÁ4ƒí}”±KsEˆ%ä¥Xûª:±¾[añ ÉdŽ±zz>çßñ—‘‹{Ê1oóž2¾8“¦±ßTÆ Z†®òæÙä°8˜~c©ó|H¶Œw‡»Ïh»´!^Jvcô™ÆQäöí‰G ©öý@Î.\ßU`hÇ‹Û~&×Mî¶m?@²®y@€¶
-Ñç v"#d¯®ó´»æv¶âøn2›K¿ÝÇg»õª_“§#ÞÄdþæqžG™ZñD†Êä:,*ÏQùƒÿŸŒŽ&çØç*Lˆ(LXQÒÈ`ʲ¥*oa†¸"ï|Ž¬Œ¯®_§ˆÇ³Ó ã¬È†³s&le•ÕدP¼0¾=3Éw¤v`,¸ñŸOï…t³˜97¾€Û ÝòùrŒùBjÙžs$žci+ êO¨È5ËY&™ÓÁ"ì]Üã°8T¹–<7 ą錸Å%W`×Ï0³H/4†qMÃ=‹uPÖ ¯å<-`LÇ©ƒÉ^}`{= ˆìÜí[Ù·Y$ÁY¬qŽÇ¶gÈ¡ŒÊ ­´–(«s:’\%…²DŸð'Á³NˆÊ‡ªô|—¿9ò7Ÿ0i÷˜./o®.éÖÙoè.ôë7C*{€”§ñŒßÅ׎ÿ?ÕOçÓ^,ó)ߊ ÿ}ô_¥(~½endstream
-endobj
-1019 0 obj
-1911
-endobj
-1020 0 obj<</Type/Page/Parent 794 0 R/Contents 1021 0 R/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>>>>>>endobj
-1021 0 obj<</Length 1022 0 R/Filter/FlateDecode>>stream
-x­WÛnÛF}÷WL]•Y–dY—
-•Q*Œ•9g½Å2×/Âme+Ã*×Åší"ƒµÌ‘K¶"`èæ-*ú9V ‚³0ˆ˜ªR!>¸[kcÔQÅ@g‘Z “h8…Ãgø„IS€‹–ˆ’MÚärQŽ2òD¯˜¦ìFS¨ B
-,\†*Šd.3KQ_
-±Ž%Ñ”ëÅ(7O„Ú¥ãS_ÊÄ€Ûn$jä¯èÛHÓ=x¸îЊëxåÛ©Â5Ø¢M£Z|Í“Ù£F•™ÒzEÙ©ÞÐRO#=guT×Ýqg 9"}Äõ¿†U‡sFÇUÃÒ¯®UŽä}„ƒ.ˆFN±¯rM.×l
-¬ß´–’+… Ù´ªº¡óí+`bнsvõð;o1ôøñm…f»\‚yNcAC¤"Ûú´ Bp$EÈT¾ÄÁ%ýÚ(B Ü
-áöN¯šTûÉšõ<}êÒ²] ð“Ýö; 7éÖ=ùbt¸÷,ì—“×GGo·æ
-áß]„S`è¸ÔÞpÔéÑp8
-endobj
-1022 0 obj
-1797
+780 0 obj<</Type/Page/Parent 635 0 R/Contents 781 0 R/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/Fc 12 0 R>>>>/Annots 231 0 R>>endobj
+781 0 obj<</Length 782 0 R/Filter/FlateDecode>>stream
+x¥X]sÛº}÷¯Ø>YéH´$ȹ/wœÏúÁŽo¬ÛL§îH‚bÐA+ê¯ïÙiɬÛÉÌLñÀâìÙ³üãhFSü™ÑbN§TÔGï–G'ŸÎh6£eÅw/.´,išM§SZ£+»U»†‚®uë@q­"þÑTê'mýF‡†TÐôämë¢Æå˜ïä&9i£LIÊ•é¶Ã°ðfùýhJ“Ùi6Çb£U«‚âÁ=m‚/ÛB“ÂÀMÑZ¨Ò*¶Xk¿|M­3ºr;â_dÓ)žã\7‘V­nšc^nr°ƒÈÖÆ­¨öð'ŸŠ† И_dgÛÃü|Ú=îQÂÓÉéÛì‚wðÔÚEãml°á _Q£ê\ÑηGÛðŠ¼º¼GŒžŠ|¯Ù5Q×d"níD­+uÈ蘩YûÖ–ŒS®r»Ãž±QÎ’dõ€¤FNÃ!`ñ@Mg…wUÆê1ÃhµJÆàøMJÆÑ?W‹Øaz QU…yéîÃ{jÚÍƇø'€»v¤ÊÒjÈ:Çßá6&#Q“Ï£B>KºŸŒ"zÿ÷{êÁª¨¦v²Åž†û)ÖºxÄ$&’o_¸§áÿHuÏ„e
+êd«B*n¦Ïk?Ÿg—ÿGÎ/DÌY]k³ZGh_aÛRwÂÑõ…‘t$e9ˆ}Ó¡ÊW"¬ p0Øb’ØGÞ‚„Ü'€B5T· þŸOÝË0zé+|h4RÂøskAÂx‘ÌÓη«53lÅIç7PQÿ€¾q¡!µ:ÎQ'¯Áñ“ð0º÷ ºÌúNU½VXU=k9kf^PhÚ#ª8Ëa »q#ã¨äzc6LFù"|x3d ²GI°ºÍÿ5{u'à2f[mÁýÿa³þÉíth ÷°LÐUk¡©ÜªU!ž
+Iâ3’Õ{~Yâà—Ù7XS ßˆ¹ H-(‹æR©o–llÒíßJ(Ÿ÷juŸLZºÛ›×‘ÈïË/Çåd¼@p¸,6>m•Ç
+‚•º"ÓJå  D²?ÃÀÌ"9ì»Zgù‡Xf˜ô‚/*@‡ñ(?î‹k“e4µCû
+·ÙE`´j¸ZbîdòXht²“†“
endobj
-1023 0 obj<</Type/Page/Parent 794 0 R/Contents 1024 0 R/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>>>>>>endobj
-1024 0 obj<</Length 1025 0 R/Filter/FlateDecode>>stream
-x¥WïO9ýÎ_1é•Â’„R?@9¤ê
-åŽTí©©*gãM\víÔö6Ô?þÞØ»ÉfÛJÕY{~¼yófòù O=|÷é|@§#J‹ƒëÉÁ“ƒ^2Óî—]àŸöɘ†ãs¼ðK+)ÃÙõÉ°z‚—½ø¶ð¶¿`èäöŒú}šdìp4>§É<èÑ$=º7^^ҳɧƒ“Ûauìè}þ”æ4‰rq1¢cZKZŠ/’æʥ拴rN‚VÖÌrYÐz‰7è­Òs³v”æJj¿BS!”öø!Áö{tÜ?Mð~”­eê•Ñä ù¥¤÷KSH÷ÜRÀ®Ì¤_K©)7 ¥]B4ùîTQ:O÷¯'lÀÊÌXÉnŽ~f’J‡`9Ž7S¹¤•ðËä °÷h4¼ØÜ@òäö¢gú{°òq2À÷6ñ‹wôÂèL-J+8³}HÔ`„‚!ù‰!W®VÆz¾‹kd]Ú˜’BR: ÒAöÀˆ±é n+
-é¥MèQ3’8Òf ¨€S¦¾"QÇh
-O-} sØ<‰†øÎÚØ'G0°–yÞ%¡’ &¡†Ž¸8Àü'1TÖ뤮7@ZéE¸²‹ztÌŽ‹k¥óV¥á¢ø«Ò{¾¡¨‹ä¸dìQÛC
- w!z5qÐ5ÊuуÞÈÕ“äz´|»•LU¦@Þ]} Ú³×'¯J]†ýþV¨›:ÝT—Óq/ýH_Nƒ¾@#¸AÑ"÷“_™ %,ÁµÒÔü ¡ÎŒ_V,ÛÙ­…{¶ûcO†sŒîžð•øF Ö†LA´o‹ü*ŠÕÿîuLGÖÏØdìŒvMVçÇíÆa5fÞÙ®Ç~8ì^ÆÙ¦Áét)Ó'”vÍl¨M¥ç&Š"j€‘§÷Aä°ªˆÐà $fàt“ƒ³!J]MôŸ ›Áà4¤º›ÒÕ¸j =J_®bÒµ°4ÆÍ[ŽU!…xYŒL
-žºÂmÉŸ -1M0y¹CÝ0 8[~ŒY,2LaJ^Ûª‘»V•3$5´2• $· \7NóæÊcʶRÜ÷1¶ÉÝÕ}\^0¦xñ:j•‡ýî!ú¼ÆpÈðv{WŒmœ·t©´ìÒ÷ K­·&§¡eNßð×9Œ³y¤*2ȱ&„Ôß uªú^Å ™?†Ç­4' ¾a•™£*_` 5¢à©Û@@G¯ÿŒvnè#Dê#ã Ž-¥¦À>
+782 0 obj
+2245
endobj
-1025 0 obj
+783 0 obj<</Type/Page/Parent 635 0 R/Contents 784 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R/Fc 12 0 R>>>>>>endobj
+784 0 obj<</Length 785 0 R/Filter/FlateDecode>>stream
+xW]oÓH}ﯸ+m‘Ó¤!iØÕJý (…. }™Øãf¨í13ã–üû=÷Ž¤¦íRMÆž{ï¹çÜoC:ÆϦ#:™PZœ/^^i8¤eŽ“Éé”–'ÇÇÇ´LçÞ7Ú“Ó…
+:£`)¬5ySÝzPØ;[Q¥Ã£u÷TÚL¤œ¦Ìø´ñÏ›
+ÏO^§ÁØ*!Z¨r¥È7um]ð”ÙR™êÅòëÁ1 †'ÉÖå^´½9Úñ©3uÀתʨñÚQíln
+¸—[G× úlªÌ>ÆìÒ³Míåù½ÓÙ——×ozÓÂè
+î<®Mº¦GS´Òjn
+Ùüiíë£I2f‡?¯u3´¸>§xG®ÚèpŸ_ÃK€#1VΪ,U>
+M·‡«&îÝMm²Ûrê4Ìí±Ö {+9„—j¥¼æ«*ȯÁ  è‡G­ûĈ°€&Ñ ß±¾é<g~=h`±Í;8Ç"ýþ FBÇ+¥×Å€QŒ ¾OM­ò—1ÞôCÏti=ÁëkûHªÁ}®À"øÖÄš8äpB¹³%1,iaaw#æ3p"¬[~ø¤G§O¯€%zƒÁm(ÇJu¯ùƒk™ær“oãZþ<µ—ÓˆÄñÕŽê®C{É]©
+1-ÛB0û©·8õB­µƒí<ˆ½æs”ÄA§é%Újy+V’·Îoö4¬² )jËÊc³N­Ÿ¦‚`å½ï¤^¶‚O m0æ–yæMkïœÏ?,¨R¥¦Ë×gó÷Ó¿"5ÄwÊy¡6ÛjÑúœ®-ËB, ð°u étª¡@ëý€²ßRp®ü‘Wì,¤k= Tá¤[üY¼ùøÏ› ±ÕºLï0~…o'³dÂUtqDW±t-…3 fµöŽØ:°®ŒÌ²’¥ð"X¯Qw¾
+€m^{þ ˆC&'/à
+´Ýä’ÐÂTil‡¸?
+´3ýÇ„_Ü*«´g°lPÂK.«)Œ»ž›qñ3Óì˶•\Z,Ù“mõÌ„Ù3”Ô ›úÔ¯vè¿%§¿÷–ò;8Ÿã#bjãicHèŒGB‹Dµ²M8ê9ÙuM_ë´m’Ýû¦<WhÉ¢è Ž©`Ðt ¿«².ô‘ԳȇÛÛSÊím²õƒæ9›ì±ÌÚ-Ö<‹z„éqn1|-ú"¤±Ã°cðd‡aë•æ9<“p¹ê$* 5À¯X˜¶úïGÀ}5Ö‚‹ï¯æo“›ï¢Rk[`râBþ‹Q°Áö.ÊØ¥¹"Äò\¬]UÆXß,°xÐh4ÅX=>òïøËÈÅ=eFCÌÛ¼§ g'Ò4v›Êirš ©\<æ{ƒÃkV:‡$QËt·¿ú F¼úHâd;ÅAží4
+ŽÜ\^H8joÆh»a×óþèÂå]Fvº¸éFr]¥nSwó#ËšçH+y>c'20"öò*mW·Á:ÃÊ–ÞŽ&Si·»àøl»]u[ÒþpÄ‹˜Œß<Íó$S*ÈP˜\ƒÝC¥)
+ðÿÉè`tŠunžÂ€ˆº„ ¥ÝLÙµTá-ŒÀäƒO‘•éñåÕ«6âáä8Áô
+endobj
+785 0 obj
+1909
+endobj
+786 0 obj<</Type/Page/Parent 635 0 R/Contents 787 0 R/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>>>>>>endobj
+787 0 obj<</Length 788 0 R/Filter/FlateDecode>>stream
+x­WïoÛ6ýž¿â–!˜8Ší8N\`’&i,n»ë†z(h‰²ØH¢+Rqýßï)ɶ’}Û¤¶EÞwïî¾ô©‡ÿût1 ³…ÙÁõìàvvÐ ./iû§Xâ ŽõFø;¼¼àÏü)$Å|a¦ùƒã§w8Ò§YL]žÓ,rÏ{4 ;Ÿ¦·Ç³o§wÃêL' š%’tžnÈÈ°,”ÝP¦#I´NT˜à•¦”kKk]<QTJ²š¬ “\…"E$ÂèÜ2äM×î;Ó÷W·-wÞtí(Ø¿Ñ£“þY0@È›W÷“öe‘G/œÜ>þù"©}/¢L‘á·ÒXô,
+%¬Ò9ò¦éÃ5•F”Êg™6 ¸ØÑ` 9¢«Ð–l£K6Ae À‘Maª„}«däऑ\ËÈHi8 ]8 §"[Ê8–Ðä³:*§L+ ÎzŠE¡×^ŒÛÊW†e¡ËÛE+Y —|IÁÐÍ[Tôs¢Rga1Õ¥B|p·Òƨ£Š¡Îcµ,A&Ñr
+‡Ï𠓦 æ#2$›vÉä¢Uä©^2 LÙµ¦H„Z¸ŒTËBæ–â¿
+4sŒŠ
+¡:¦zJcPÅeÊg”îZ+¤ZEZäTÙ*…žAÑ‘˜±blÚ«‡·V+‘‘ÈT°°q¥ÞI{ŸÇºžu{WÓ!-¹çÑð<M1TÇîÕ jÐ{½ÆæS¸ÒŠÁ¬ ؼ H¯Ö‰x–
+²m?RdC›WÀÄœ{ æôêáw^bèñãÛÍnµó˜Æ~†HE¾ñiA„à6Lˈ¨|…ƒKúµI„¸ ­^ Z5©×“- ëyø4¥dÛà'-ºív@ÜkzòÅäp¯ Ø×ÏǯNŽþvÉd{cd¿]w'=š êTDµE½â‹ôe™ê…Hÿb^Ö!B&[ÜføÍ“5†&ê5#;ïp‚ò‡à^™¿ñŽ{„ãíédpî×s·€Bòl‚eŽÿj´Ü"»ýÊ´k¾ññùüèÓ|ÎB_Ýà÷Ó;a?#ÿb2C¡B¢L±Ð"2·´é•“$Ô…=M¼ÍÊ^×i-6a~fxõ÷Í9ŸsùY‡›x¤;89b#­~à‹*t¯!4‘{@”ï–_Åx¿Çº
+endobj
+788 0 obj
+1796
+endobj
+789 0 obj<</Type/Page/Parent 635 0 R/Contents 790 0 R/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>>>>>>endobj
+790 0 obj<</Length 791 0 R/Filter/FlateDecode>>stream
+x¥WïO9ýÎ_1é•Â’„R?@9¤ê
+åŽTí©©*gãM\víÔö6Ô?þÞØ»ÉfÛJÕY{~¼yófòù O=|÷é|@§#J‹ƒëÉÁ“ƒ^2Óî—]àŸöɘ†ãs¼ðK+)ÃÙõÉ°z‚—½ø¶ð¶¿`èäöŒú}šdìp4>§É<èÑ$=º7^^ҳɧƒ“Ûauìè}þ”æ4‰rq1¢cZKZŠ/’æʥ拴rN‚VÖÌrYÐz‰7è­Òs³v”æJj¿BS!”öø!Áö{tÜ?Mð~”­eê•Ñä ù¥¤÷KSH÷ÜRÀ®Ì¤_K©)7 ¥]B4ùîTQ:O÷¯'lÀÊÌXÉnŽ~f’J‡`9Ž7S¹¤•ðËä °÷h4¼ØÜ@òäö¢gú{°“q2À÷6ï‹wôÂèL-J+8±}DÓ`„z!÷‰!W®VÆz¾‹kb]Ú˜’BNˆ9€ÒAò€ˆ¡é l+
+é¥MèQ3Š8Òf ¤
+O-} rØ<‰†øÎÚØ'G0°–yÞ%¡‘ "¡„Ž¸6€ü'1TÖ뤮7
+y£ÂȾxåGÃtD³ØäæjÂ*š¢ Ó˜hK4,s.­£Î£_wR—n‹éž¼YuºÔAŒ -× îÜK¿4fÞ‰ÃjPKæU%lFû°BéÃ/¤]pYjÎqæRÖr‹¾vèdÔ‡¡èéåt
+uç§ÓC8AIʲéäçÞª=@lõ
+¼0søqfMAR¤Kîjy‘j ¿i¬sævš˜‹ `[aö±¡7qæ9m¤c˜Ü’—=Œ¸…ÓNj§¼Âåç-çÚt8]cQö¿ÝºR±R^䔣¡¹l8\¥%ö3üÃJ[égO]á¶àOΖ&†¼Ù¡nOœ-?ƤFf°N%ïlÕÀ]+‡Ê’J™J’»®§yïe1e[)îûŽÛäîê>®.R<‹xµÊÃ~
+÷|Þ†@c8d„õw»†½Ž ƶ΀[ºTZvi{†•Ö[“ÓƒÐ2§oøë†Ù<RäXBêo:Uý¯b†ÌÃãVŒ“ß°ÈÌQ•/° ÈQðÌm   ‹£×Æù:7ôõ‘ñÆþÆ–RS`€kŽÖÊ™1> ‹ü1–ýzÓîÇ·ðÎÏ}ËSЋ°Ý‡1r§RkœÉ°‚Ç玾q¾Íý94Ø1¡ÃWf¶KC5½1LØCd<XuAÇËAØc9Í«
+a7„[èX”ópD ßïCb³; £ÆÀ„Wèÿ_D²^z°ë³»“Ûqõ¡ ?$}Îã`z¼º»¾b|b^ܘ´, ÛÏÇ}DÎøØ5?Š’¾?Îé¥Æj\†ÏEîŠs¸\ÑßCö˜ÆÑ Ï‡ð,žõù lü ;†Mendstream
+endobj
+791 0 obj
1681
endobj
-1026 0 obj<</Type/Page/Parent 794 0 R/Contents 1027 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F6 9 0 R/F8 10 0 R>>>>>>endobj
-1027 0 obj<</Length 1028 0 R/Filter/FlateDecode>>stream
-x•W]sÛ6|÷¯¸Ñ‹œI±ÇŽóÒqœ¤õÔqÓFi¦Sv: JˆHB@Ëú÷Ý;”Âôc:öƒe¸»Ý½½ã—£S:ÁÏ)]žÑ³ Êë£Wó£§oÏéô”æ%¾¹xqIó‚Nf'''4Ï?6…vôÉ4…Ýzºz>¡÷Ζ¦Òž”Ó„ÿ6•U….¨t¶¦°ÒxÀÔÊíèÎ.m3£Û’v¶¥•zÐß~MÊ?™>:¡éé³Ù"o*£›@¥utotUѽ[ëÖ~<á ¹eÓgÑTq$ò¹3›@[ƒ#‹oSCý´{Ðn6ý_™Ò8á ¥ým:)ú”Ê檢Zå+Óhš"+Z˜@j©LãƒÔ—Û&רƖ䬪M³¤Tò„L„Tù5Õ:Uqv1;g
-è`Óg p6!ûœ âl0¢0Ý)Oª"ßn6ÖO&dO&$‰Hƒ?¡î„굟@·à$§VÊ£VHÝ·y®½/ÛªÚуªLÁ…H4e¯+áÝ4èZšNÏÑ”éÚAþ Ü=K€ƒZhœÔcp¬üÚËضƯ˜ Ÿú8ät©Fúþ;¢ºÒy ñNûñ?–˜ºèê9å±Ùs[ÃPÚ x ˆ‚| í×Án&’‚_Ù¶*¸©Õ¢L¬  {Ö%Ž*,ŒCF~ä7:7¥A©$G‘½
-«—Ïqe*8@®¦Üá»®‡F¯cf£ >å½ÓM;š ÂŽ`“K§j?’[F𰕵žVÁQ}ôCá8wšIÂÖ¼îO¾’ÃAPØ $ÑeaœH¨v#¡m²J¡¥2@%š­#” ¹h§b jBVÅÔ6²àò!Æ—ÓìÉŒzÙ{‹´H§±X§²u8äúÐâ Ñ…iÞÏîðŒ©Гjkí–‘á®?Å¢„郱Ó+f ƒÔÔ´€ª¸¦4Áp8Ôš-P£·¦œxãÞاž)°¶0¤ðö`ô1Ìr_ºè)Ì™Çèç¿‘`7ñx€
-&KH;g! ~Þn¯žªHcF‰sÒüW ?ƒµð¬ A×4 šitœRü4WîtmƒN@ÂÏ_)'…õ#ˆE4ÎFÞ¥è4û!äDÈ4YÕ„ ã|-q>6æQÀ vµñÞXŒ!Î
-ãt• ³ÏŽÃ
-PáwˆÓÿ„‰w^”Wǵ É{{Ž©Ùl¿:ˆ¯zTl¢c¬•qnéoVH\‰G¼ÌóóŒp1¬yo4_Q”×ql`Wùë £ìµ²˜Ä¼žÅ/QÖxâÙšúéÙÕì‚[êÙ¾.äsFQ&Aÿ>¥Ë’W.¨‘ýú!ñý(;Þ—•)
-hŒü4Õ’MöD¬göúzÎ"( ì产Y\mËïe˜$¬´¸ŒÐ¨˜£¦ÛvðçÓnÂ…ÝbÔM®ì{¬ù˜¨ÉÑ:‡½ÿt×ïÏSvX®•Éîr§ƒ>;ÐetšŽN˜P²¸ÖùâäËp:Y•¸¸®mñæÛíªƒãÏãç§o_t}uz~6;¥‹Ë«Ù fðÃõ»W׬’ÏLÒk›·WP>ɾ¸ÄãÓ˳h¡g³3¸ßmJ³l<G·xïrmÎgüK¬Ø!pá×/Ý›áG~åéÚMÞ§Ï/Ï^®¼¼ä8oæG?ý ÉKÔendstream
-endobj
-1028 0 obj
-1802
+792 0 obj<</Type/Page/Parent 635 0 R/Contents 793 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F6 9 0 R/F8 10 0 R>>>>>>endobj
+793 0 obj<</Length 794 0 R/Filter/FlateDecode>>stream
+x•W]sÛF|ׯ˜â å*’–d}ú%%Ëv¢:YñÅô¹RA*µäš
+ò-´_»™H
+~eÛªà¦V‹
+0±&¸'"b,\pìY—8:¨°0Yø‘ßèÜ”¥v’Eö6*¬F\>Ç=”©à
++êG‹hœ¼KÑiöCÈ5*ˆi²ª AÇùZâ|n̳€Aíjã½±Cœ&
+‰+ñˆ—y^cžƒñ.†5ï抲ã:Ž ¬ó*_cÁ`”½V“˜×À³ø%ªÑ/P<[S?½º™]rK½Ú7Â¥ücÎ(Ê$èߧtYòÊ5²_?%ž¢eÇûñ²2E‘ߦZ²É^ˆõÌÞÞÎÙC…A‚\÷4‹«mù½ “„•—u
+O¯Î$™ëÙõ æwg›Ò,['Ñ=^»\›óÿv\7ÔõK÷bø™ßxºn“×éó«sD—/Î8Ì»ùÑ¿þ ÍÂK¢endstream
endobj
-1029 0 obj<</Type/Page/Parent 794 0 R/Contents 1030 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1030 0 obj<</Length 1031 0 R/Filter/FlateDecode>>stream
-x¥X]oÛH|÷¯h8œHŒä/Ù>܃wà l|¹µÁbµ0FäPbDr¸3C)ú÷WÝ3¤dût H49Ý]]UÝôŸg3šâÿŒætyCiuöÓâìãç+šÍh‘ó¥›Û9-2š&Óé”éyºÑé–üFSjj¯kïÈäò½±&/JMòZž;­iTšµ©åʈ2íR[¬tF¤Vf§—Ƥê ×KíµÑ:m“LJûañýlJ“Ùerøçò›/Ï$!rcûûÇD•Úõš­Tºm*r²ú϶°:Kˆš œî¤›xéâš&—wÉ Ÿþ”“*KÒ¥Ó”«¢tc*êÔj…ïNU+õw‡4WíšP•z‡;ÉZi¿×º¦K)d6 }DúdÛ 5HH{òV¥
-y_üß~9©|¿A,(sæÓkt¥ë;åÖTò›7Éþ!4ŸÀ¸ûF-ä,ÃêŒÅƒ@טjËS+“=†1ì”ø5Xº»ïœ<³ÅN„sxØmL[fL,6:ÚÜ…F×2¨Á’<…Ý?‹€ãˆyò½­C[z-×zßÅ枌Ž%tÔ e$oRCuB‘4¸ZE¯¦Bê=¼¢v+<P¢ˆðÀF—°`Œ¬X9U8Úæ&
-Ç2¸AðÜòAè¼ÅìŠ u-Ïy°2¹)3
-³pÕxá¹^;˜!ûe˜ôA\]YX·¾gÀ1{ ѳw=¦¬Å¼cà„kàz¢]H˜á•÷ºj„ÿǽ/9‚ 2ÅÐb<ñÃÔT©Áµt}~{9èúdž<…yܵ½oÁ˜iòpTžlB!pMw˜^ôäû;FMSqJ<*¯F2üE®Ø‚€Íž[¢Ü èÑ£v[ošÑ˜FÏÚoŒÉøã‹WÖÓ]·áœ„w<£ŸS@Üé2gM:ˆ1@Ðâɘë$Þí9YôšF+‹Šx;9€ /?Aƒ…€`Ô´¶a×FÄ´µX<XØÖ[`ÝÅé¬ä7¬P<1Ù
-ùÌ—ZVÑÏXx­)髪u)Ô6ͬå){ nâ.“-î\qFcþ5°—{ä6@¶7ÕGA,k\665Î&5H?õVfÈù—Y2§1Š–Ž'9È͆5ˆþÖî
-æ蜡¤¨òmPSÅV„üE0MSîtöÎ9‚ã_ô;šÊù¡À׬XÃHÅ )c§BÙˆÇF /ÁVì]¡)Œ–Tn+˜ï éVäD#5žõÊà»ðëU§“¶.ù•eä44ZøýSÂF/A.öÐ õÒ(çöÆf7´E±1jBòOÏ?ÿúÛ×ÅÓ¿ŸÿÃcâA§ÂòCt‡ J ÷ @Ñ$*Ë
-áåÈù-ÇÁËßÎþ“wendstream
-endobj
-1031 0 obj
-2002
-endobj
-1032 0 obj<</Type/Page/Parent 794 0 R/Contents 1033 0 R/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>>>>>>endobj
-1033 0 obj<</Length 1034 0 R/Filter/FlateDecode>>stream
-x…W]oÛF|÷¯Xhë
-òPƉ<Z“wìÝѲþ}gõ‘:!A©ÛÝÙÙá?'jã¯CÃ.](ÎOÞÏO.>õ¨Ó¡yÊ_ FCš'ÔŽÚí6Í㳿²ç8£n_”Oã!µ(7VRlò\jïÈÊXª™XšÒÓtN…5©Ê¤»"¿ÂÂI2iø\_y7ÿvÒ¦Vç2ê"ÐÙc.¼—Ö=FîâÓc^:ÿHK> Ëpüt^:i£›ë9{N©±$(:ÞØÍ6èùö¾Éõôïˆ}œŸ  .ñÞ ñÞÅ %¤UåãºrÜsÙ íJït£QÔ}U:1kÇõͤ}‘–ÏÞÁ†rºƒ¨ÇåÌW‡+GÚø•ÒOä 9o
-Ú˜’\!c•nøk¡‘µð+Ô,|¸˜©gd…·ÌÄÂ+£;®Üý²­Ñ§·Êó#09HlÊ,Ù†ªŽçkôSäc)NäD¾Ä{(ê؆ĺ´4›¼o.‡”8mWˆkG¡«#È•Ea,˜!ul7…GœB8·66qûéFÑà:Ò¿F£2ÖF4[ Ë8Þ×tC]~-¥¦¯ã>j`ÆÐWcŸ¯pìEíªgýºáî ´º£ªo÷ƃÐ
-lÛ˜ ^1B–”ŽË=Øšâô(Ë@>®¢&
-ÓR½=ü×o3½+ÂuÆøRÌg —‡‡£v l•~æwÇB2´4O¥;§%†k%^$ÓŠ™INOùˆg*I@¤‹w»¼ 
-f^„Ìë\ålË8Fâaºö6Ñm…#ðÓ´:tÇ)2@Š€‘^XO©Kº éžyQ1Eçoãrº×_`~»½M=§T‰J§]‰Jàû
-U؉륈Ÿ! ªfÔ…Ü
-[%Æ `/3-}$_¿ÛD5±ª ÙRSjMŠŽ¯‹µÒÚƒÎ^vw< útâ2Ôfù¢Lé
-ƒy²Ö•Kðô˜é WµK‘ÑE]B׎†¦Ûí½-Ÿ0")›¼1oÿýùGts7¹¾>~¸›Îî>GþÕÓվù1¹@Ò8i“ÑÏ4cPÑbK›ÎpÁ vÇìyîsŠ[x·ÎI­•ü£Ú‚uúý&ã7±Ó9Þy°9k¡(
-©õŠ=†‘´êIé Ô¢ôX èÓrC˜•¦ßi.má
-–‘xAFØ‚³„»”²“0{.€O;
-»2ëjDð°Â¦É¢
-Þ ËþÝn-Ñn·Ã"2ôí wM"äâ•Ì_0äöâÓhë_C
-1‚äð±½atGÇüFåÏ“ÚËendstream
-endobj
-1034 0 obj
-1723
+794 0 obj
+1803
+endobj
+795 0 obj<</Type/Page/Parent 635 0 R/Contents 796 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+796 0 obj<</Length 797 0 R/Filter/FlateDecode>>stream
+x¥X]oÛH|÷¯h8œHŒäoûpÞu‚3°ñåÖ:‹Õ‘C‘ÉáÎ ­èß_uÏ’iìÓ%0 ÑätwuUuÓž,hŽÿ º>£ó+Jë“Ÿ–'?_ÐbAËœ/]Ý\Ó2£y2ŸÏi™ž¦…N·ä M©i¼n¼#“Ë÷Öš¼¬4µÊ´:uZÓ¤2ÓÈ• eÚ¥¶\ëŒH­Í«^}˜’j2\¯´×rDç´Mî—dì‡å÷“9ÍçÉâŸÊo¾Ü?‘„ÈîŸÕj[6R´Vé¶k©ÌÉê?»Òê,!>h†rú“®â¥³Kšß&W|úcNªªHWNS®ÊÊM©lR«¾;U¯ÕßÒ\wBATéWÜIÞÐZûÖ K!‹y(è#Ò'Û5H¨EBÚ“·*0Öl¬ªG•¹.-HḴͺºågíkÓ$ú‡VÆl‰kVÍž´µ|¼nõ.‰‡]%±½é¨P¯šTšj'iª†ž–l_µ2p `´Îã’'àeªÀØA'ÕHÈDZˆ&7‚øpN¹‡õ‹Ú"䛂§\‹þÁg‡öòçVr@ÅqÔ×2-v%ˆ3¥3‹v…„…—•y®­nP%)‹Ûøq&&·þUUàfh^€_þ´<“éòzŽÆ_Ü\ãó~ðt˜™{@Ž›7Ô¿In’³ä2¡oe“™ã\¿»u^ùø\$sNñ ð·oÌ7]Ó8b\XÆ4Rq¢ôªï
+¢ ò(1;=ó›–(9vn„PeÒY
+¬55fG®Õi™—€ÛÖt›
+,…$mPÊÇÏ—;
+z2^߉¸õžþ^mÓŠsÕmn¯iF% çPà™g‚qwÄPô
+ÿD[³@ÌÕª0µv«U¬Eú?*(+]
+瀮q”Hˆ`Q^ª€°dØ 4X Ž Ôªl<~ †`\N¥eÈW8ÊìÈl~—Lþ W¯Š
+Í höÒÿBie h¸½HkÑTDAS"«qTÈûâÿöËQå»5² @ΙOoЕ¾ï”[SËoÞ$û‡°|ßµ”³p ‹36=\cF¨W8žZC—l1Œa/įÁÑÝ]oä™-_õD8‡‡]aº*cb± ÐIq7MË KòxÔõð,fŒ#ÆÉ÷® m¤Üè]›{29”ÐûO/0”IP¼ÝK Ô EöÒàj½d
+©7vÿ‚Ú=®ð<‰"Â…®àÀ˜X±rªq&´ÍM
+Wãa €1
+ö®ÐFK*·5Ìw”t+ò¢ƒ‘ÏzåÎ@ð}øíª×I×TüÆ2q-ýžþ)a£— »oÇzi•s;c3‡›÷ÚM¢Ø5!ù§§ŸýíëòñßO‰ÿá1ñ ˆã
+ûøù&¾',ÎÉ9XÈ Ôéóý—Ÿî £à;ûÖƒI1ͱŽ3$Rÿâê·Ï®Ïð†ì4¼e±ÛEó¶“åÛès|€#þ_]ÿËôDî¹ «‹ë D—/Ï9 ^ýþsò?B$“endstream
endobj
-1035 0 obj<</Type/Page/Parent 794 0 R/Contents 1036 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R>>>>>>endobj
-1036 0 obj<</Length 1037 0 R/Filter/FlateDecode>>stream
-xW]OÛH}çWÜ—ª©œX <¬D®ÐŠÀ#T)/{’L±=îÌ8©÷×ï¹3vpM´ª*Ñ$ž{Ï=çÜëGã߄ΧtrFI~ô%>}=¥É„âžœ]œSœÒ8Ç'·¹$zQEªw–f1ͯî£Oñ÷£1OÏ¢SltŸJ³•†l\JR…u"ËdJÂ’T8Ê 2ª •Ê$‰"¥Ò¨Â‘ ƒ—‡§¿ÿzzx~¤6¯Øï”.H›æÎÉI4å;ÃúÅ'<áÃE{
-ãT¢Já¤Et£s¾òZÎ范›‡û«»å2_J3¤G£raêv]Öeˆöݽ_DòZ•ïW.>E*+rämÉ™JÒ
-Á=ÌGSz¦¤¹OqH7j­
-·ñ9z´GǪ\e¢ŸlitZ%Î h’^Ñn£’G¹“êLE¦‹5í€|§„ýòÅšrQÔTJ]¢&ˆÃâ¯4¹më@V•UÅzHVS&ÝGN°&§)ɤ0ž$B™þÉ·àBݹ™lmÌQ€_kÛÕÜøZ¹V–/H…KaeÀvÿ3§PP…sÕ{I¥MŒ ‘QN‰Lýؤ
-T&Ÿ¹FŒ*J%8kÞK’?*µ.`¼Ÿ õ“n„Ìua¥'™©
-,ˆ… ½Û;’ÅV]ä8ª—†È€æÁ\
-\e)!½ªÔEDw£HÜÐ#õÿcc@Õön–\i·E8àSø–‹š
- @į…Þñÿл4¸1“Ñ6ÒzœùsàHŸJ±_ÕЂ½cOÎL"\
-ºæ;Ù»`^A‘¢B)}´ÎW5·2ÛByK ×ô¿Ôž£ h &WÖr¿^A]žo‰B¬ÑQAšT÷
-w ñçʘwS>ŸÎÔhòh¼ƒÇ¤W`KK˜,´ã^(…UðxÏ$¦r Ô<øyŽu{ úë{Å înûh· qXÌ}o4p—ö÷Ïci¿ã5íDqøjôô.zQ4¯K{ÏkzŽ/&K§m§~ éÜ )` lš§ÄRJöà \°·,ŸáèëE3lMÎΣ }>áW;ðâËÞÉôwì›VR1„~ æ@Ãâãó)^RÓÁd]DÓˆ_îüÙa\¾Ã›'·GHÁ^âÍË9žþàÎOã
->>#X¾ÃÏ)|ìéùit—`y1æn㣎þgÂ$Íendstream
-endobj
-1037 0 obj
+797 0 obj
+2000
+endobj
+798 0 obj<</Type/Page/Parent 635 0 R/Contents 799 0 R/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>>>>>>endobj
+799 0 obj<</Length 800 0 R/Filter/FlateDecode>>stream
+x…W]O#G|çW´.á$¼ØÆŸHyàŽ\Bt‚}º‡8BãÝY<ÇîÌffãŸê™õ¾païzº»ºº«öŸ£µñÛ¡a—Δ–GfGgŸzÔéÐ,ç£!Í2j'ív›féÉ_ÅSZP·/êÇñZT+)5e)µwde*Õ³ÌH,Líi2£Êš\Ò]_âFá$™<¼o®¼Ÿ};jS«sžtèä¡ÞKë
+wñ—顬 P8~2«´ÉÕ匌=¥ÜXT
+ oìzôtsßÍåäï„ý:;B%4œãµ7ⵋ?”ÇÊÇMå¸ç¼2Ú•>JFI7$ôUé̬—7•öYZ>z‡ªé’W3[Jœ­iã—J?’7伩hmjr•LU¾æ…FÒÂ/Q²ðáb¡žêbØ
+“
+¯Œfè¸p÷ó¦D˜BÜ*O°ä ©©‹l*Ï'6à3¤ÈÇRœ.ȉr×PÔ)  ‰!uiizóa{A8¤Äi»x"®„ŽG««ÊXCêÔ®+8•pnelæöÒŒ’Áÿ4¤>LF¯¸2Lhº–a¼kȆ²üJJM_Ç}”À|¡¯Æ>9aì%íز~ÓîNwˆø­î(¶íÎxÐYkkÁ*È’Ò©±à¸×@RÜ€¸ÀÇEraž0+ñåþ·@·~›ÉéÖã-81}=i¸<|=h×€Vé'~uÌ $C óX»SZ`´–âY2«(“…äô”Oh~r¯R`‘D*9¿Ë ÚÀ/fn÷¶Y`z”¿?æàNÎE]x´úäôDsü¼›Ìç_Þz¸®’äù-+ÏTO­NàU¦5ŒæMŽù´@ºVdÌ|ÎüÖ¢”ÉÝÕô˜T¾?*
+ û£Èóy3_Ç CÔÐmo˽ÔŠÙp9¥Õf^„ÌÛ\ålë4Eâa¸öÑuÄøiZ ºãÀ EÀH/¬§©k:£+éžxO1E§oãr¼×_`~»½ÛzŽ)JJ§%%ð}‰Î*¬ÌŠÕB¤OÕ° ÚBn‰¥’b
+P°—…–>‘/ß­¿QCGl*C¶Ö”[S†¢Ó‹ù|¥´ö`àÚ³çÝOƒú
+)çj‘–ÎØP?K]‘ñŠ†‚a"š´Ü¡báó…XD&g¦™_UÊ3^ÁP*Ì+žŠë/75P ’¹gÐ(-!Ê€²Y܃æ@‚¶r r,ó€Y®,zé1«<÷=5•Š» î˜Úÿ~SÍŽ, {8dkoêqz“í­à0('kM‚§‡ÌH÷@¸ª]ŽŒÎš¶pí¨ñÊÎt»½·Õ>$g‹7æí¿¿âGÉ8¡«Û›ËëÉÃÇÛÉìþösâ_<]ìû›+S
+äü‘s6ýDSv‘Öt†£V°;fÇsgœSÜÁÛnÞ4RÉ_jüW§ßß&ü¦ vºã Æ;6c)U%u¦^°Æ0‘V=*tZÔ[mZ¬é³Ôô;ͤ­ÐdÒ…ö†äñ±(ƒ+ýH‹:÷B°àhRap!ô~„QØäßa¥´Ç¥ì}°5£þà“ÛÙ¯t±Û8ìvoØa¶¤ã×XÒ‡,QL³•p ‚RZÉü
+ 9"ñþ<€Œ°:g s)e3&a<öL
+Ö »îÝnÑn·Ã"è1äíUﶉK—²~ÁŽsسO£} P|T;™^Þ|¸d+üê•Ik~6 Æ—¿Õê„›[Ã.žç²“è¡yÀsõXC]ø1ãZ¡:å÷PÞ©ô*HÓ½%£ìBÁáS{ÃØNì÷øLÊŸGÿVCendstream
+endobj
+800 0 obj
1723
endobj
-1038 0 obj<</Type/Page/Parent 794 0 R/Contents 1039 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R>>>>>>endobj
-1039 0 obj<</Length 1040 0 R/Filter/FlateDecode>>stream
-xmRËn£0Ýóg™.â‚
-äühJljÈ)ÛuÙ›
-EnàIÝ6èzä"Ïstrµ5“ êMùôn"mñ®ÁHo
-÷¿®ñàõD<¼Z†—ÎFïŒQÏ«‡«Ëç ÛЫ =½…8C’Ï/º×,Ǻ؈’¬Žø¼f1¿³
-;’óyvGžBY‹*!t£
+801 0 obj<</Type/Page/Parent 635 0 R/Contents 802 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R>>>>>>endobj
+802 0 obj<</Length 803 0 R/Filter/FlateDecode>>stream
+xW]OÛH}çWÜ—ª©(+Q +´"°ÄUÊËØ'SlwfœÔûë÷Ü;¸&ZU•hÏǽçžsîõ?3:¿ÓÉ%ÅÁ×è`úí”f3Š2<9»8§(¥£ÉÑÑEÉÈ­EIn-‰^T™ê­¥yD‹«ûɧèÇÁŸMN±aÔ*ÍFJ°1–¤JëDžË”„%©p”!AU.TI™Ê%‰2¥Ê¨Ò‘ —£—‡§¿þ|zx~¤­6¯Øï”.I›öÎÙÉä˜ï ë—Ÿð„݈ÙQ%ŒS‰ª„“AÐ.øÊk]:£sZŽnî¯îæTÈ"–fLFÂ4ݺ$¬Ëí»{¿Šäµ®Þ¯\~šP¨¬(·%gjI‚{XLéE˜Š>Å1ݨ•,ô(ÜÚçèaЫ
+•‹a²•Ñi8;& I:£íZ%kr/Õ=™Š\—+Úù^ ‡å‹4¢l¨’ºBM‡Å_i
+ÛÕ€dµUåjLVS.ÝGN°!§)É¥0ž$B™áÉ·àBÓ»™lc,P€_kÛÕ\ûZ¹R–/H…±°2`»û™ „‚‚S(¨B¹ê‚¤Ò&F„ÈÈ(§D®þ lR%*S„Ï\#F• ¥œµï%Éjµ9.`¼ŸKõ“n„,ti¥'™©K,ˆ… ƒÛ{’åF]8j†ÈæÞ\
+ÑP)á
+ÄÌH‚¦Ã<™%{S
+
+»Vú5‚yuºb·aE ƒK¾;ÐßïõJ´Ç­o ¨¿'ж
+$ô4S²Ý2«ƒf'}1,üúabžÅû‡ˆEG¦–àáȯmÊ^¡lkÖ=ˆÏîŠòâYͬã^£iþ *ÎQBha¾q›Íj¤ÑEþvIP%\[
+½’ùYãMS~°ÍB;<dŠø‹Û—#5ÁüÙÈÒBí;Ô»‰ex;<œoõ‘ùyÊ`–AEÐÌÖ¨ã/=«Ê1u2uØñ¡Ä 
+>>#V¾Â)|êéùéäïÀ8ñógþá6:øûà?Q$$¤endstream
+endobj
+803 0 obj
+1722
+endobj
+804 0 obj<</Type/Page/Parent 635 0 R/Contents 805 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R>>>>>>endobj
+805 0 obj<</Length 806 0 R/Filter/FlateDecode>>stream
+xmR»nÛ0Ýõgt³’¬HB7; C“´Q·, ue1¡H•¤äï{i…÷ò<õ'+óW )±©¡¦l×eßn+º'uÛ ë‘‹<ÏÑ©ÕÖL.DÐ;ùOôn’ÚâCƒQ¾îoðèõ$yx½ ¯œÞCÏ«Çë«ç »ÐSÐ^¾B%CJ5ž#^t¯YŽu±%+XñyÍd~g ;©ÞóyvGžBY‹*!t#@Ú¼˜–,fé£Vz–‘À^<ÍF+µ³pCZÁÓözå‹ „àÎÔ~±¨íþ‹èà6ž¥$-Xwt uWnšÙÒq+Ž,CÇÀRö:Dÿ)èM—q¨Ë ›©Ú†ï%O–ÊÚSeE݈T'·uV{Øm¹÷J*rdê01ÛÑfB_/¯Ö˳U+ZQ
+puƒÞü’Æe1•’ ßñD1²ßdä—“SºþÜ1S ÚPH¨US‰–ÿ!Îþ²>™ø™ý³Á•endstream
endobj
-1040 0 obj
+806 0 obj
383
endobj
-1041 0 obj<</Type/Page/Parent 794 0 R/Contents 1042 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 270 0 R>>endobj
-1042 0 obj<</Length 1043 0 R/Filter/FlateDecode>>stream
-xW]oÓH}ϯ¸Ò¾)qã|4 ¡¦ÀÂÐ%‘ºð0±'Élm;còï÷Ü™±ãº°»Z!UØž¹çž{îÍà ¦1þÅ´˜ÐôŠ’|°Ú Þlãh¹¤ó³ÇØ&ÓEtE³åÿŸNñ_#iÇ7ðfÚ?8~ùö9MÆ´ÙÁúÕbI›Ô}Ç›äâæ ÊJŠ§½ÓGª4]' K‚V"¹¯Kz­s¡Šg›¿cMf¸~q£‹Êè,ÃEUàämmdv¢µÈ·‚Úiç*Çã.Ç0šÆÑ„ÍÀiÑ­‘F>ÔʪJÒg)RUìÙÛåÛÅq¸2Yð…•ÜiäyÒ5%AµDÞîR”¥Äg4¤2“ÂJÊŽ$‹
-$¬g’ý"—îD)¬…´ýBÕ©ôUfVjcà1"Úä¿z4²Ì”´ž˜ÈU¤wHŒÍXÀV×UëjHøBò‡ÈAz÷¶ÌD‚œ©æPmÏoiôNá<³ú*õ@¹£´«³Œ\rðÌøñ눮ñÖµY7˜Ö@Ci”‹S*Ð`hBg¸çÝêQ" !)­¯?8³¼\EN`
-Íœ•æ‘v8aéëÅŠoD\OâÖfA‚N‚Sx‘ ˪šèòÄqó«N–-»*‡ït€>€’°bкEE)Yi¬þ;óÑRC;†˜yæ®6†¶’R¤ÓK]È4êùË}»?êiž>Gádw¤ ¨~?I ¢úT;Š)/A˜â'N¶' ®ÙjÄyO&‚§#ꜰš‡À9¸]!¾ •±ÎDôÚK7£ÐË·RhÑ¢Õ!Ü
-Ë£Ûj‘©O®Ÿ,
-Mç
-kP˜›³!ˆíOƒð¶Ý9^+è·xë5  „‘.Ø´¥çïq #ŽC¿[< ¶;ž=à
-³™[.Õaû(Nþ6|È1Ö¬Lg}F×iëW‘žÏ*1Úê]Õ”NñvÂœó+Œ[úwWeB‹†
-endobj
-1043 0 obj
+807 0 obj<</Type/Page/Parent 635 0 R/Contents 808 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 234 0 R>>endobj
+808 0 obj<</Length 809 0 R/Filter/FlateDecode>>stream
+xWÛnÛ8}÷W З°Ë—Ø.PqÒlóÐ6[Èmh‰¶¹‘DE”êúï{†¤dEIw‹A%‘s9sæÌø±ÒÿBšh|AQÚ[®{ï×½a0ŸÓéO±ÃÃFãYpA“ù ÿñßBÒ–oà#Ì4püüfA£!­·°~1›Ó:¶ßñ&:»Ú‹¼”-ú TjºŒJ†-EôPåt­S¡²×ë¿{CŒ&¸}v¥³²ÐI‚{*ÃÉ»ªÉ‘V"Ýj>Æ­«Bˆ»Â`#6³€î
+YÈÇJUJú"E¬²;;¿™Pú£Ÿ_Ê­F–G]Q„TVIdmopå^Š\>}Ê)Œ¤T<H2ˆŸEiï
+<D:…­RlIUîÙàVíªÞI° |dÈp~ù£N8ôé<Þ)&Ó`îŸZYðñ8ÂÇ6Ä–»ë+†5–&*ÔFÆ.bIئZÖJvf/ piðáóýúóÓS¶º|*8EJÓYˆh!F E͇6ôÓñÓê/‚Q`ë¼+t•ÅlíÜï9`+|AO%.ÞÑ­ÿ”Šh¯23fhA'‘™x’èÎÓc%Mih[蔺x0¥(•ÎŒ%’Í’áØñã^e±>ú´öŽºßËLþ€=A•qfù*û¡Öñû“å>
+Ÿ^p©3!¾ÕqéÈÞJñǨۃ¡½BÄ{ k…5Éþ3‘J{"ÆÀGÜ|¡ò˜»"3)uQÀc@´ÞËõXÈ<QÒ8^
+ W’Þ"I6µ`[]•«>á ÉŸ"çíÛ<rF¤î™C5¿y¡·
+çž)ÑV±Ê¥m•$d“ƒgÆ_t‰·¶ËÚÁ4jF£\|œbþBZÃïF"‰iuùѲ˜Åå"°ò8·iyÐô
+>Ž_yŽa…áaG± 
+žr QuÉÊFÿ® YiúèÇ(©êyŠþj˜çuu4ÄTcÈÿºc&ÕRþäáoªúÃ{€lbA° »¼ÄyûªQùzi
+#W¾rûi…†a=GI6(Z¡E Â4všhŒ0òF­r‚í¢ŽÃ*SØ‚šÀì˜õAl^ ÂÙ¶çx« WáÆI öÖ‡BÚ`㔎¿§ €48ù"¬ð¬S¨P…ÉÌk¿|dG÷ë=ÔÛ 6¦“<£iû´q›HÇçGÚèmY—Nñr”sŒ]ùw[d|‡ú
+endobj
+809 0 obj
1563
endobj
-1044 0 obj<</Type/Page/Parent 794 0 R/Contents 1045 0 R/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>>>>>>endobj
-1045 0 obj<</Length 1046 0 R/Filter/FlateDecode>>stream
-x¥WÛnÛ8|ÏW`6bùÛ)°(riP?4é"^ ä…–(›Dº"×ûõ;‡¤lUMÚE;’ÎeÎÌêëÉø7¤ÙˆÆSJË“«åÉûåÉ ™Ïéø£ZãË€F#ü˜ÌgÍÇJRÎà¢~àîþí '´Ì|:LJÌ_Ð2=Ž“q2LèƒÙQf¤%AŸMõdpÊhÊ•ÎH9‹k¥PšR£]eŠBVïÞ,¿œôo'4†È½Ñ ‘O/énI»V<å6² ðpùñêŽvB#° Â¤¢ ÚÊŠœ¡•$QãíT*œÌh#,ÿÝWr ÄÙÔCù#Îz¬‹rS‘Ï’ÐÂ…žÜFYZíñEé52ÞIwµ¸ -JI_kYíýS}]™z.ø ¿ SŽÓI'¬­K€åû"ÝÉ}—%>++ÊÑZ¢½•HŸ(¯Lé/s.ÅW¹ï %°S¡ñÛî€FaÖFw2W1¬³ - iãÈl¥&+ÓºRnOS üʸÏמç­,dÊÀ>ž.ïoîßúÑ£ ¾vsMéÆX©ßtò¾PlkJ0@ˆ*¡ËÜñ(yij]"g!ûwKi%3µ(,êá1ñL:¹¹ò- G¤ìñ “ãþPÑ ûÄfˆí¶2Ï¢H8–×ЀÎç°%J²iÓÖÇùdš¼ QBŸÁIçþ ´DéÙk2à»å3pÙì(=ݽ–Ä­6=!&¾F¢C
-Ê„Ôo‚±]ÿÒØ>+ˆ
-µì‹¨â ò kxå³dß`Õ¶`ëâÛÀAgRroî`½î¥C~P)¯Un YB2óÁ:‡z—R”L=ž1 ‘k¡ixKc—n"…Î&9À¯Y‹1‚'—ÂetòeÊn`¬¡V³~ðÛQPÇ)c¹`‡ó^ë9o PBÐıc°|ñïˆþ–lW°_!• p‚ïJ¢Fñ,T!Vª€¡5yŸ_›eýñqž‘¹ 4;¡·†Ñì©•E¹˜8DóyV© ‹‰O¥]m”ÈaΘ™nóq<‚k?·”ÑÅ,™v—îy³rc¬«éø½æ*l)X–˜¥^GR¡ho¹nSbÌsU0Ô3–iÿãåõ‡ÅÝûäaqCÊoÎëˆ vm8z¡0N?ÏØF \¦žñzS¶¼Ü/l —æ,sŒ¢¬ñ`ðBÔì/#±†Ã0+|l”xt?~éÛØXD'#:#ÖA»µc,Ø–b67 ˜‰÷NˆöoÓxˆéÍ’95MgñzsÈá˽ñ…Ÿæ)ƒû—Vß‚¿g‰•°í>ì^§›ÊhõÏÏ*ð”+¨ae6»»Ój_º´ï ØUÿ=V¼µ4ÞóË„Ql¯D¥ÐÁ¢1Ä‘AmØ—¥ÈäAº<¤¨Â†¾¬Ç»Åîñ#r‡‹å›Ùp’tü€-ØÃý Ë3µõ•éùî´P°Kxa]dÞQÁ*©M½ÞðB;äò×;É‚é‘Xo
-endstream
+810 0 obj<</Type/Page/Parent 635 0 R/Contents 811 0 R/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>>>>>>endobj
+811 0 obj<</Length 812 0 R/Filter/FlateDecode>>stream
+x¥WÛnÛ8|ÏW`6lùÇv
+,Š\ÔM»ˆÅy¡%Êf#‘®HÅõ~ýÎ!)[U’vEÑÄŽ¤s™33‡úv2¢!þh6¦³)¥åÉÕòäýòd˜ÌçtüQ­ñeHã1~Læ³æc%)çp Q?p÷àö‚FZæ>ãCæ¯i™ž^$gÉ(¡fG™‘–}1Õ£uÂ)£)W:#å,®•BiJv•)
+Y½{³üz2¸Ðh÷Ç3>½¤»%íZ!ð”ÛÈ&ÀýåÇ«KüA8Ú À‚
+“Š‚j++r†V’D´S©p2£°üw_É1gRt–Œ9ë±.ÊME>KB zreiµÇ¥×Èx'ÝÕâÓ=iQJúVËjïŸâèëÊÔÛpÁùm”rœN:am],߇é†Lî»,ñYi\QŽÖí­DúHyeJ™s)¾Ê}?ƒ”ÀN…Æo»…YÝÉ\IÄ°Î&´4¤#³•š¬LëJ¹=mLð+ã6>_{œ;´²)ûpºütóé­=
+âk7×”nŒ•úáM'ï Ŷ¦D„¨ºÌ’GÌ1Û5 r2ñ¸·”V2ãQ‹Â¢Ϥ“›+ßrDÊÞ08z$ì#˜ ¶ÛÊ<‰"áX^BC:ŸÁ–¨¨¦L[ç“iò\ ㄾ€’<7Ný8i‰Ê³×TÀwË'À ±×Qyºz-‰;mZê!&¾Fžƒÿ™Ñ’ ¾˜Êú@ä溵QŽ:~…å‘Ö+† ,fÀ|þH]b;ü­–Âò4S³Ýw¦p(°3g–£HAÿØB/P²¬]-ŠbÿƒÂ=ëù¾#`ÂH´'8™9ÁÉdþl‚“„®¡«{Q®„wº‚.!ô›`k׿´µ/
+’Â@-»"ŠèA|¡o §|’ìz€œÚl\|èLj@íÀ¬Ö½tÈ&å5ã Êm!K@f>XâPïRŠ’™Ç#æi!r­3”â ohìÑM¤0O Ù$ö5+1Fð<ãR¸ŒN>LÙ ¬ÔjÖ
+óõ ¤’¢NðCÉáAÔ(ž„*ÄJ°³&oãò‹`²,?¾3Î3|f4
+d#ð­Q{¼Û”í #÷Û³å€9‹“(k<œuóËH¬á/L
+%½Fú¶ÿ5ÑɤzdÃ.h·vŒÓRLæfû2oâòÀà qÀÁmO0ýY2§†áãé,^oN8|¹vá‡yÊàþ¥Õ÷àî™pb%l»»×é¦2Zýó³
+<¥Ä¾jØ—Íâî´:.x{v@Õ'ï,õü2a›k'Q)t0èF qd–e)2Ù#(—‡EØЗåx·¸Ç=~_Dîp±|3›Žq¢“Ž°{c¸”`u¶£R"=ß
+n +¬‹Ì*X%µ©×^g‡\þz'Yð<+𠀉4•–Ïi¶3C>åò,½›q—9 ©®ä‹|9ƒ8¾Æ—)Kß³%xÒaÇ(Ç?(Õ–«8í#™>ÝN¯žÞž\Þ'WP¬«Tú¸‡b$Ú¶Z~‡¤qĦz±µÆt_k­‘Ê¥Þ#˜ó‡U²&Ê­šym ÅIp(°°ÓÔ“HÔlZ©-¦Ç £±xr¢×v0¼L`ÇóË/\g°µpJ +Šq8`ÝÉv°_æ/BÔ@ðDýñ'•~Ã[¥9¿?¹y5!Ê ¶9¿p5­cœßš_»Üy8ø?W;¸Ò¿|àúçþÐsÊ‚3ül<Ü8&7šN“Þ=-ýI>Wæ+h€£PŠwœÛ˜üT4áæþlŒÅìÿ½(NfÅÇ9ŸspÉÿ<ù1M©5endstream
+endobj
+812 0 obj
+1589
+endobj
+813 0 obj<</Type/Page/Parent 635 0 R/Contents 814 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+814 0 obj<</Length 815 0 R/Filter/FlateDecode>>stream
+x•TMoã6¼ûW< ‡¤‹Z‘GvE‘ìnкM==ÐÒ“Å­D*$Wÿ¾óhÉqÜöP,ê}ͼ¾Ì2JñËhµ ëœŠvv¿™}ÞÌÒd½¦·‡Ûá%¥|u“,h¹^áÿb‘¬É1U’(s| üê!¥[ÚT(£Ô¦ŒŸSÚ—¥m•6Ô*ØÑ÷dì·›¯³”æ"r
+hì΀½D\=,)ˤæ<£ù"Ç(F¥P3ý¾kìV5Ì=A[C¶Šç¾Ý&…5Õô~ÿécB›Z{ôÿ“}ŒÁYÓ €³Óq(©hTËô|÷ÓýÝ7Y1Mx}hº×¡Ž©¿=~y&Ïî•ÝX•¥ÎÙmÃ-©C‡wµ!Š¾p¸üù™vÎöÝ¡Y¨U-+(i›nù8 —´¨µàI
+î}[åáÅÔ
+åò°}€`ÁŽwrZÄ':†Ý&‘œºfyÿ‡kÖã5™å«Dnvܺ'×o´3=9û7%ŒYô-6¡äÒ”!懬ù!íò»l¹Z¨ÒòòæV
+Âä¿Ìþ¶þÄendstream
endobj
-1046 0 obj
-1588
-endobj
-1047 0 obj<</Type/Page/Parent 794 0 R/Contents 1048 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1048 0 obj<</Length 1049 0 R/Filter/FlateDecode>>stream
-x•TMoã6¼ûW< ‡¤‹µ"9Žì=E²»Asè6Ûè¡è–ž,n%R!©¸ú÷GKŽã¶‡Â€`QïkæÍðy–QŠ_F«]çT´³»Íìóf–&ë5½>Ü/)å«›dAËõ
-ÿ‹dMŽ©’ |D™ãáW÷)} M…Ò9JmÊø9¥MqYÚViC­òý@Æ~¿ù6Kiž¡!"§€Æî¬ñØKÄÕý’²LjÎ3š/rŒ‚`T
-5Óï»ÆnUóÇÜs´5d«xîÛmRXSMïwŸ>&´©µGÿ?ÙÇœ‘5Í
- ²JÓ$ŸdiMªººÿ@ÙRžÒMžGq¼Ê(»Nn’,¡ŸìžJKHë]¨ œ0añò~YtÃ?¾ĶX‰z~sÞ*æ$QöáÙxô ¸}TËN-a¥Ð¾¯Ù0ÖO±RmìÖHI«JŽ`Eàã&?#~ \]x¬
-SZWŽ¤a,<
-û-R¦<™à¹œÚF}?KgŠÓf÷/äPÇVt7 mxlmVÃÊËÛƒ˜Ï&‚»ü Ø:ð_á?÷úE5l‚O:PÛû
-endobj
-1049 0 obj
-813
-endobj
-1050 0 obj<</Type/Page/Parent 794 0 R/Contents 1051 0 R/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>>>>/Annots 283 0 R>>endobj
-1051 0 obj<</Length 1052 0 R/Filter/FlateDecode>>stream
-xX]sâ8}ϯ¸5/CªÀ` Ùª}Èv:½©ê™Îv˜éyàEØ´±-d‡æßï¹’… Iv>ª+éKº_çž{Äï1Mð/¦ë„¦W”ÿZ^Œïo(™Ðrƒ7W× Zf4‰&|’>ìDUKCñ,¢§ZUnéIkñ£¥_¬4ãŸDºS¥¼\þ÷bB£d†ÝƒÛ4ÕMY“*7Ú¢VºÄß$Jú|wûHwÊÈgx±‹¦q”ð°GôؘJ[wôø~FqÜ®J®yÍr§,e:m
- S™´©Qkii§÷Tkj¬<Ì‚A‚?dûað:CâµÃm@ñÔ{T‘)DäùÁ!3Ž©ÞI²ÅºÖî³Õ`¾º¤ÊeDô€ø-ás8˜a¨Ýb#EÆsþã@;5´V¥Ô”xckQfÈò™}½ñ¹Ku™ÊªÆ¦2k7ïµyæ²tQ"¤—ž UâÐ<—¼ºG
-mäImP.Ì™IaPÙ•j ÒÊöBá”´Cªr)c#70…„s&6:Ïõž±Øi#>ñãò‚Ñä E1ÿõõÓE<™DSš'‹hA%ÈòMû”Ócàœ'7xÛã—J–A#r¾žk¶4ØÕuõñx¿ßG‹óLT‘6Ûñérç–ïÓU£k˜à³Á*¹ºv§Ãïx>‹àG<Çø^º§ÖË–ìo|…u}Õc.JYóv '_™?ò_Unc„Í6•ŒR]Œõý{Á̦ьf‹๠Å4š´¯BÁ‹›‰C}G?ëZz ·%íPP<EFO;+9’íí¿:ùË_¥âžzlÖ¹²àýcmC±ÜNë@¬ m£2x¥}gpk?l- ºÍ
-U*‹žE«cÓN¥»¶Y8±¥Ì8Š‘óh:ÜHèL T´›†;½)
-i†àÇIâàÌ$w…L2í5‰,Ђ§EôƒÕIÑ1Þl!Týâ]KÚɼÚ49 ㈠(›3¬f  Ry3æíS×
-³dvV%ºí®µ¸=ï>Œ¸WFÿþòmùåti—ÒB¨²Æj} ‡m)R¥éƒn*)šÈYøÃ&¹ž1°b†
-ÇôÉ„ó3]\»Fáß ~àä&Là0§s?rºæÃ4L"z`ûY“r–Ø]æ' øŠ¦ÉÜC=¹hŸ^¥¶[®Ý¹ËþL¯²<ÆƬôÎE§ Êím²•þ3ÞÎâÓ·½g¼½š
-/ßC÷8 1ÀÀ£–ÿqP7¹‡'Š€WŒ¼GGlôUGu{JQÈ!}þi <™uvnZ²@€Ó”îD $Öªàyªñ±ÉÅòE¼1P´–( «–Nr¼¨§@Þ
- £­¼qcX y r(+²Ø‚¯Ü gÉR¯ ê¼Xâ9N{Uï{œbëµI. b)›b á¤ÉjÊÒjàô_çn½ÓE¬vuéHDб(ëÝÃüî{7Ï)×ú¹©, ^€6+iXKâH+o ø 1DõI½ ;A^µº¾+HO ¯÷šSÒ÷»=§BBºþÎõì³è’e •¬]sس–‰ €)!†G9Î`†‡éƸ[°AÂ’y>³•xH8±‚x†”^]á.båT‡¸T­u]çFžH® BŠè Hl)¥Ì8±Lcà¯L~o§Y/¼c<±•q‚ãM@nBœ½ÅîÓ'a:Ô)VH£yâ$Ä7£)Éx¸­s ]ØðÕ;¾šÅ9¸#b#«\¥<bE§›]ã9šfeŠSÁzqU\3êӶ{Ær.7Õ^ëËïÈ-Ô9žun[Z·mŒóÐùÆÊt5ˆW—çMÂè?;.¶v÷îÒ½aE”ºžU\•#Æ;2ägÙ›™"â8"Î2*q ¿6Ê];7È[áîVh¶>y±t<|o&„Ž1$ ì i2ã8?s½'gD]ãBÕpû \®
-Ù]4p ´&¿WªàLmC<X†eÚW™c´£2îÛò€íUw5øúpjx ‘ÿ'O#\’“·ÜO_M^3!W(A†ëIª0:ÜEø»Ë´RHQ:Ö
-7Bìâv=]„4f´ÇM-CH9.Y‚¢¹nZÍ£Tp'…tÄêOö·L×ùô….ANîþÔ6,p…­(²5ª @oxa5¨Œ|Q€T~NÀŽHسÔ]ðÜv® öÃ?_( ±Éjâu¼·~øõ‰j#%³2äEÛ` ÄÆtÀèq¾É5U¥MíIñ .ÞÓµHŸ%`ºÈhŠ˜„–xzŒø*†å¾Åº‘ ˜øÎ××ÙúõrÜ® èd‚ˆuQá¦í&ip2”%€æ›—4¼Cyâ/.˜0T™æ ßí·Í¿ã®hjÍÊtÅ“`衱¸9n­N¨‰g÷HûyÊxŽ»¹ïG܉Ü
-endobj
-1052 0 obj
-2085
-endobj
-1053 0 obj<</Type/Page/Parent 794 0 R/Contents 1054 0 R/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>>>>/Annots 292 0 R>>endobj
-1054 0 obj<</Length 1055 0 R/Filter/FlateDecode>>stream
+815 0 obj
+812
+endobj
+816 0 obj<</Type/Page/Parent 635 0 R/Contents 817 0 R/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>>>>/Annots 247 0 R>>endobj
+817 0 obj<</Length 818 0 R/Filter/FlateDecode>>stream
+xXMs㸽ûWtíeå*‰)É©ÊÁ¯7®šÝqÆÚtHPBL\€´Fÿ>¯B¤d;›¤¦ì1E
+“¨èóýÝÝ+#SœuàMl<Æ.6>™ÇQÂÀZÑSkjmÝÑÓ‡Åq·*¹æ5«²”é´-%LeÒ¦Fm¤¥ÞS£©µòh0  þ†Áë ‰·wÅsïQcD¦8Qw„Ì8¦f'É–›ZX»ÏÖ£åú’rUȈèñ[Âçp0Ã:ѸÅFŠŒ-üÇvkh#¬J©­ðÆ6¢Êå3û:÷¹Ku•ÊºÁ¦*ë6ïµyá²ôQ"¤× UáТ¼z@JmäImP.Ì™IaPÙ•j ÒÊöBá”´cª )c#s˜BÂ9¹.
+½gg,vÚˆOüiuÁhr¢˜ÿúúóE<›EsZ&7Ñ •” Ë·ÝSAÏŒI€s™ÜâíŒ_jY9MÈùzz¬ÙÒh×4õ_¦Óý~i,.2QGÚl§§Ë?X>}H;TM®a
+€ÏFëäêÚ¿ãå"‚ñ¿Kšãxéž:/{X²¿ñÖ ýUO…¨dsÌÛž}eþÌU»6ÛTÔ2Ju9=Ö÷ÿ f1´¸¹žKº™G³îáM(xq;s¨ïiàWÝHᮤƒJŠçÈèéqg%G²½ý7'ùñ«TÜSOí¦P\⡬m(ÖˆÛ)`ˆ´mU¯´ï níçƒmdIwY©*eѳhulÚ©t×5 '¶’G1qMB‡é „Šv“Âp§·e)Íü8Kœ™ä®If ½&‘Zð´ˆ~°º5):Æ›-Åj£_£I;YÔy[0ŽØ€²%Ãj‘0Ñ •·ËhÙ=õ­°HgY¡ÛNqàZ‹{ÀÑóäéþÓ„{eò÷/ßV_N—ö)-…ªü€¡6zÜV"Uš>鶖¢œ…?m’ë ”=s­¼Dcû§7ÈB“,˜Åó…ãøuE¥Ú¢X<'˜Æ™ßr£Ë"|¼ÿéîó??ŠÉQ-ÒK´E ™{5•¢[éÈÞSÙÖ F&pÛÂᥠ`ð9ôÓJs’“ª1 788WÛÖ;ün’Â1C2áüÌo®]£ðï?p28 ÁùÒœ¾ùÚ$¢G¶Ÿµ)g‰Ýe~‚¯hž,=tГ7ÝÓ›ÔÃ6`Ëõ?w5œicàUVÇؘÕÁ¹àêy‚r{›leøŒ·‹øôíào¯f
+ä½°0úÑjÀ7†•¢€b°"{`€-øÊÍp–,5ø
+ªÎ‹%žã´WÍŽ°Ç)¶A› –ª-7.Lš¬¦,­GNÿõî6;ÝZÄj×—ŽDA=‹²nPÐ=Ìï¾w‹‚
+­_ÚÚRÙâh³–†µ$Ž´òŠO±CT?«Wd'È«.@Âwé)ÁáÍ^sJ†~w§ãTHH×ß…Þ‚}Ö#]±Œ@£Šµk{Ö210Äã(ÇÌð0]Âw 6HX2/g¶2 'ÖÏÒëË1ÜE¬œê—€ª£nšBÂÈ‹ó
+i²Lœ$ƒøf!%·M¡ ¾zçÃW³8‡wDld]¨”G¬èu³k<GÓ¬LqŠ#¸É "®ŠkfXuÚvÏX.dQíµ¾üŽÜBãY¶£uÛŸ oì¡J×£x}yÞ$܉þ³ãbkw.ÝVD)ЩËñYÅU5a¼#C~–½›é "Ž#â,Ó¡wð+WîÚÁ¸AÞJw·B³ ‰È‹ Ô ç àãx3!tŒ9 a``H“ѯÀù™ë9#šª–Û?ÀHàrUÊþ¢K@ 5ù½VÝgj3àÁ2,Ӿʣ=ð˜qßæÊvPÝõèëã=¨á=Dþ‡<Mp}HzLÞq?A~µEÃT„\¡®'©Âèpwáï>@,ÓJ)EåX+Üý]°Ûõ tÒ˜Ñ7µ !¸XdA
+Šæ~¸{zì4ŒBRÁ:Ы?Ùß2]çCЗº9¹ûS×°À¶¢Ì6¨.
+endobj
+818 0 obj
+2086
+endobj
+819 0 obj<</Type/Page/Parent 635 0 R/Contents 820 0 R/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>>>>/Annots 256 0 R>>endobj
+820 0 obj<</Length 821 0 R/Filter/FlateDecode>>stream
x•XasÚHýî_Ñ•J•I•H`ÀûéXg}g{}×ÞUùË 0±¤ÑjF&üû{=#„ Nv/¡Ñôë×ݯ{üçYH}ü„4Žh0¢8;ûuqöyqÖ&:¼•k\ô)öƒ! 'c|‚ •’Vünb›æ Ë{7C
CZ¬°ûh2¦Eâî÷iwb­tiÅ2•´UvC•QùšDN&[˜mB+•Ê 2*+ÒÌ©ˆ%}hîð~¸›M)Q¥Œ­.wHå$Ò”ìF~Z|=ëS7ŒwW™Ì­°JçA}3ÁÜ\l$<ü¢•ÜR¡Un YMÆ–ÒK]YÚn„å­‰ïÝDµƒn—½è¦‰(ŒÈüͽ÷J´4”kKE©ßT""Ø#‡ÜTE&N°–r%ËR&
-ty9DYd4èO‚«ú*¥¹+\^•@ª–¥@HÌ£^Z¡ràsaxœÎîh®WvËIùÒq Ò”—³‹ël¬-~éõ¶ÛmPˆ$ àfïx©«I^úò ~ý¦·n]¸”J$,¦Î=0¶RëªD(NRÑ9N…ˆ_Å`ÍRî˜`ÎJëBr~¥§«.O]
+ty9DYd4èO‚«ú*¥¹+\^•@ª–¥@HÌ£^Z¡ràsaxœÎîh®WvËIùÒq Ò”—³‹ël¬-~éõ¶ÛmPˆ$ àfïx©«I^úò ~ý¦·n]¸”J$,¦Î=0¶RëªD(NRÑ9N…ˆ_Å`ÍRî˜`ÎJëBr~¥§«.O]
špN*·'JçÕq/¸†Œ¦•ð±e!ãH¡Æˆ
âK©«âv†/¡IƒaÏñ¡¼ºœ#?i6é¼›Ó~àâ¾sZ[uùýv†æÀú­·<``áÄ÷©°"cØ»UO·èo¦Š7œ½©\ ÀšÅ.GÕÒ?¬åÄ‚lK †_S5Nÿ xHŽ[Íæ{Åf³Üú!Fœp2AÂf'¨
µX\²Øµ¥ÌTËLùùùP×-©ÂKÿO„ÿo©.Æþý üOäagf°9<¸Ãs•a>fc‡|l8¶:YQRÉbÃØ8Cæ€5Áë_§5ºú;û©·Cx®Üá£O¢ËKñ±9DàÓníóÃí€÷Fw$ÎôXÑ`Aãl…Ž…çÄ#!ä~m÷Ó©#ˆe4Q8ÂTµ¸:dÍá (Úó%å6<p"!!ãi↷’—Ž Ök×˧šrå©(|2Kížv'27M°¸£rtßñUƒúVëïÎz·9A÷pjâÎ#Çö=j!™Žzž—\(ì1°Æñ &
-&[cC^uùv'píüGÞaú mK•û#k‹]$2—(`còû?;8P>GO¬zÞ9ò½)áž‚æå O_×ä§ÚŸâlPh-m±ÍEö‚cÄI`L ¸—.øXÊUÄíÇ'¶½l]Ä•2W)Rk# ÛÌ¢·ù¶7¬r ISˆs¾ªr@uÎn¬q(ŽmºÛ‡™“‘h˜‚O¬¶K9¯Ì&ÎßÚUä¾â9ò ZÑwb€Ñ]`P¶5Ó,ÿ|N#¦ôÄæ¶x¸sjó9
+&[cC^uùv'píüGÞaú mK•û#k‹]$2—(`còû?;8P>GO¬zÞ9ò½)áž‚æå O_×ä§ÚŸâlPh-m±ÍEö‚cÄI`L ¸—.øXÊUÄíÇ'¶½l]Ä•2W)Rk# ÛÌ¢·ù¶7¬r ISˆs¾ªr@uÎn¬q(ŽmºÛ‡™“‘h˜‚O¬¶K9¯Ì&ÎßÚUä¾â9ò ZÑwb€Ñ]`P¶5Ó,ÿ|N#¦ôÄæ¶x¸sjó9
endobj
-1055 0 obj
+821 0 obj
2114
endobj
-1056 0 obj<</Type/Page/Parent 794 0 R/Contents 1057 0 R/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>>>>>>endobj
-1057 0 obj<</Length 1058 0 R/Filter/FlateDecode>>stream
+822 0 obj<</Type/Page/Parent 635 0 R/Contents 823 0 R/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>>>>>>endobj
+823 0 obj<</Length 824 0 R/Filter/FlateDecode>>stream
xV]oâ8}çW\©¥R „ï>¶3ÛU¥Ýîì–yC™Ä€g“8µþýž›8Rf&•¢_ßsνö{'¤þBš i4¥(í<-:¿-:ƒ`>§ÓËlð1 ‡)^ãù ïp:
-†d$­a; Ñp‚O¿4ããÜÿòn¦óTÆCl.½ nÿùÂ1-ÖÈh:™SZÄåî-¢n8&}ÒÙZm
+†d$­a; Ñp‚O¿4ããÜÿòn¦óTÆCl.½ nÿùÂ1-ÖÈh:™SZÄåî-¢n8&}ÒÙZm
£² ½‰t%h§Ü–þøüøånñ½3 ÞÖqeôW.3^¤ÈoNéŒMûÏc
Ã*Zo8ãM M*‹’"–d‹<×ÆÑZr[|s¬Ç(ÒEæH¯¾ËÈÁ–DvŠ+ƒ_µ9•æ?iîi­Œuˆœ؇Ï/dà¬ôØh+SËD’Ód‘Ç·ö<[:zªÄÿ1ñ) „7£µ»¡jyâ—»Q^å]GéKõ5Ib‘÷«ÐýXx—¯rïî€0çÑÏ*8÷Ò­
-@í-\_À\´6´¸‚2ŒP™%·Ó$œ3jU8iy?Ø®ÑÜmU´¥X¢¸˜Š\g¤‘±¡¾6 2Èm¡âÛ“'RûÖ*“13ÚJ8Ò+ÀVÎ`?¾@ìm¬lžˆÃ«Håõ8ðD Èg“Kcuv%$ u<¡:ÒkŽn%¥d¶’5Wq ›•„Š!¯Ÿgð¨·î“zhóRn77ÔÓ± f–ýÛ…e“Zv#$S+Øù^ sbZ˜Q$nyWW€Äê®»’NO+|ÙFý†kï¡‘F&eŒ0ÜÑÍnþåP-a°2Ýk„ÿ‚«æ4ùXz‘E:M%F—ÛòI­é  Ú þ“Ç<VÉ?ÏŸ†£Á \½¾¼-ï<- @l›–‹œdÊ6´ÜPF€‡}žq6­Æã æ+‹£Jœ‰s[áÊ”SŒ duÊ¢U$-¡åËïª+(Õè‰ÂÊu‘$§f·÷(þ_ÞÄíPWä'òZ'‰ÞñÉ"÷"Íy_“C7)˜êÂ@f–R‚Ã}<¢DX “e—gC®­U«äÀÿ¨½?=ZA½Úÿn4‚K;™$Ë»ë­G/¾b°VCQ;õ7Ͷ:‚8m[–@OîýV&“ïÞ¨Ñ<µ<òÕ·t¨<ße"]v/´*;Ĉ=µ*åFÚû£×ºKx2xÑåqív%òQñUÇXk8>úldÚÔ:G¯s h1^™Þ&<Ä[˜ ±Ò¢b]c(­$s:‹kª>l® ¯EºÂÄÏ1ÑSñ•ÙæÇÌ¢¬Qõuo©äˆ_=FUÐò67 ÜÚ.ß¹æþ¶Ngßùútºu½=þùôH_Œ.o<ŸuTð9^¢zÕ®^µíÇîhãÙS½¼¥ÍgŒ2ü»ó?i endstream
+@í-\_À\´6´¸‚2ŒP™%·Ó$œ3jU8iy?Ø®ÑÜmU´¥X¢¸˜Š\g¤‘±¡¾6 2Èm¡âÛ“'RûÖ*“13ÚJ8Ò+ÀVÎ`?¾@ìm¬lžˆÃ«Håõ8ðD Èg“Kcuv%$ u<¡:ÒkŽn%¥d¶’5Wq ›•„Š!¯Ÿgð¨·î“zhóRn77ÔÓ± f–ýÛ…e“Zv#$S+Øù^ sbZ˜Q$nyWW€Äê®»’NO+|ÙFý†kï¡‘F&eŒ0ÜÑÍnþåP-a°2Ýk„ÿ‚«æ4ùXz‘E:M%F—ÛòI­é  Ú þ“Ç<VÉ?ÏŸ†£Á \½¾¼-ï<- @l›–‹œdÊ6´ÜPF€‡}žq6­Æã æ+‹£Jœ‰s[áÊ”SŒ duÊ¢U$-¡åËïª+(Õè‰ÂÊu‘$§f·÷(þ_ÞÄíPWä'òZ'‰ÞñÉ"÷"Íy_“C7)˜êÂ@f–R‚Ã}<¢DX “e—gC®­U«äÀÿ¨½?=ZA½Úÿn4‚K;™$Ë»ë­G/¾b°VCQ;õ7Ͷ:‚8m[–@OîýV&“ïÞ¨Ñ<µ<òÕ·t¨<ße"]v/´*;Ĉ=µ*åFÚû£×ºKx2xÑåqív%òQñUÇXk8>úldÚÔ:G¯s h1^™Þ&<Ä[˜ ±Ò¢b]c(­$s:‹kª>l® ¯EºÂÄÏ1ÑSñ•ÙæÇÌ¢¬Qõuo©äˆ_=FUÐò67 ÜÚ.ß¹æþ¶Ngßùútºu½=þùôH_Œ.o<ŸuTð9^¢zÕ®^µíÇîhãÙS½¼¥M‡Œ2ü»ó?
+endstream
endobj
-1058 0 obj
+824 0 obj
1030
endobj
-1059 0 obj<</Type/Page/Parent 794 0 R/Contents 1060 0 R/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>>>>/Annots 307 0 R>>endobj
-1060 0 obj<</Length 1061 0 R/Filter/FlateDecode>>stream
-x¥WM“ÚF½ó+ºv+A[µć‡=à¬×v•í8^n!‡A@ö !3Òbþ}Þ´>€µÊq²vËÐ3ݯ»_wÏüÝ h€ÿEC…ï:¯׋ÎÀŸNéôa6X`ÛhêOi<ð}4‰üŒ¤µ;)ô4ØߘQ0¦ÅêÃ)¾$,Ð"ö‚±?ñ‡>ý¦³uº)LšmèQìVâfñ¥ÓS”{ýÅf´Rúàvî…;™KcIÀ¾x©+%)ÍÈîV~ ­¤3u¤Cšo©Ô9¬tz½žûµ§±·bwiУƒ°P«"‘ wÔ FþÐ!‰õnŸª¯ïÄ®ÚýÀÅàó›Î(DŒÂ ôÇ´#„*ªŠ;gË…3t&»ˆ%+C,‘™0ˆ ê<ˆÎ²V1Â&òœ\yÜ‹3„=ñ–Ã0âp
+825 0 obj<</Type/Page/Parent 635 0 R/Contents 826 0 R/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>>>>/Annots 271 0 R>>endobj
+826 0 obj<</Length 827 0 R/Filter/FlateDecode>>stream
+x¥WM“ÚF½ó+ºv+A[µć‡=à¬×v•í8^n!‡A@ö !3’1ÿÞoZÀZqœ¬]Å2ôL÷ëî×Ý3wà@ÑF!Ż΋Eçå¢3ð§S:}˜ Ø6šúSO#|M"?$#iíŽ@
+=Íö÷fŒi±†úpŠ/ Ë´ˆ½`àOü¡O¿éln
+“fz»•¸Y|êôÆåÁÞ0ÂAo±…­”>¸{aÄNæÒX°/¾ˆT‰•’”fdw+?†VÒ™:Ò!Í·TêV:½^ÏýÚS‰Ø[±»4èÑAX¨‰U‘È„» ê#èÄz·OUƒ×wbWí~àbðñUg"FaúcÚBU E³åŽÂ™?:“]Ä’•!–ÈLDPuDçY«ay·?®<îEÈžxËaq8€¸Ä7pnÕøxqÂWɦc¤9ld­øN)sHcŽÕ)Ý%Ri¾Hó °“™£`¶\4`k˜9£“ìl¹£ÙôBöïŽLf`ákÙ ‘ì@³${Ž#QˆŒÔŽðâäH%›ŽíI#û °‘Kówpm±^§_Ÿ6!ÿ5X^œÀV²hæ4id?6t¤úì:U¨êç€ Nõ6áÅ l%‹&.²ì'ÀN‚¶ÊÛk“ÿ?¨J9¤ÉpÌt¢ÀEW,
}
-„ÌÑ!/ÑԽë[âÒ›,o.÷ÔÍ£ÈÐW7Ðœ%d5ZŸR”éœV=~/E;[i¤OôV$Jù–¡ƒî•d¥§Y$äÓõmC s/†•÷÷óO”¤Fƹ6GŠu¡{˜0$¬SÕÐÌõÿ€zC—-´®ëkêÖô•Ž…êÃìJôUºê׶jYnûŸ¥WBýõìgrÿ¬Œ1qò#Ý9\%Ý
-ÜáœR¶@€«8»ã+}
-ÏÜêân/5Êé6‰ï˜áî‹6›«öÌ“ÝË8]Ù®ª2±]K[ms&äÒ?D¡rë
- ×Ge€Î|¹¥£.Èny¶ítâªÔý"¿¥ÖÕDªêQÁwJHŒàʵV̸D
-UÎÍ C"Ï1÷‹\Zî4ý‡iuÓÂW‰1‚ó¯æôÉhcº×qá<f@¯ÜÞ‹†ü8øá›l¡“÷M§î0òòGç gÚ endstream
-endobj
-1061 0 obj
-1427
-endobj
-1062 0 obj<</Type/Page/Parent 794 0 R/Contents 1063 0 R/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>>>>/Annots 310 0 R>>endobj
-1063 0 obj<</Length 1064 0 R/Filter/FlateDecode>>stream
-x­W[oÛ6~ϯ8Èæ¶;Žíȃ×-[‡ÄÍfÀ¼Ðe³“D¤ìúßï;¤$+Z»õa-[EžËw9úëbL×ø?¦ù„nfçßo.~Ü\\G‹ÿ˜.°ìî.šÐt1Ç÷é4š’‘”ò¸‰mÚ?X~õ0¥ñ˜6)vŸ-æ´IüýkÚă'ïU!-‰8ÖUáðå¢;™ÐQ¹=¹½$+ò­X†%¤·eìâLX;¤•u”©?%UVšó>ý¬ò Í”ûÖ¾Ù|¼¸¦ÑøAo’AU’ÓtÒX§ s{m»¨‚%*M¥‘…#g¤$ú‡X>S!riKË·þ7»×U–p½³.uuÿ“ÑUi‡I|_fBµäïÚì.Û
-µD’†Vëµßøyùä+mUì²½ *[‰,;¡J…¯ô•tñU–ˆ2â-¨ÙG8¥ JU&_ÞDõY“ÚŽb¾/hÍý2)¬¤I4‰n†~;ŸTÝÏœËhOÖÉœ”¥-–&„]KmÕ§:ýˆ6{ÜË%—Áí… [÷²Ë…ï70Âa€ø=|•»ðˆèA*ôуb`ëBÓj3òˆ ÁÕÌù_»LoEÖ;•CÊt,²:Öºž"×t»¸‰5!& EÇ«‡;£NŒþÛ[€¾ƒþñ4šG´–qe”;ùu‘ÎçwÉ3š0y›=éy⎚T^jãJ[jÅ¢Ìe¾•†Ž{Y
- æ^¡ÎvóãêÝo<oÞXQ¼À”‡ëÙ­ü7<;htÅ Ûèç¿o>ŒÞé,{uñàoå’“/Fª <©¥™²¶’A /YXÉÚì’l¾
-[
-#A$(b*ª¬a0ZÌ,/@Ëþ5ò{{ðW·5Í!tu ÷° ^Þ
-endobj
-1064 0 obj
-1779
-endobj
-1065 0 obj<</Type/Page/Parent 794 0 R/Contents 1066 0 R/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>>>>/Annots 313 0 R>>endobj
-1066 0 obj<</Length 1067 0 R/Filter/FlateDecode>>stream
+„ÌÑ!/ÑԽë[âÒ›,o.÷ÔÍ£ÈÐW7Ðœ%d5ZŸR”éœV=~/E;[i¤OôZ$Jù–¡ƒî•d¥§Y$äÓõmC s/†•·÷ó”¤Fƹ6GŠu¡{˜0$¬SÕÐÌõÿ€zC—-´®ëkêÖô•Ž…êÃìJôUºê׶jYnûŸ¥WBýõägrÿ¬Œ1qò#Ý9\%Ý
+à(÷_¶‘™4Bá"Í ¤dRÙžJ® 0±]oПÛ
+endobj
+827 0 obj
+1429
+endobj
+828 0 obj<</Type/Page/Parent 635 0 R/Contents 829 0 R/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>>>>/Annots 274 0 R>>endobj
+829 0 obj<</Length 830 0 R/Filter/FlateDecode>>stream
+x­W[sÛ6~÷¯8ã>¬²#Ñ’,Krfü ¦u›[ñVšéìŒ_ ”% 
+KHï>ËØÅ™°vHŸ+ë(Sÿ•TYi.ûDô«>É£4CRîöÝöóÕ˜F“[½MUINÓYWüa68Ì´í¢
+”¨4•FŽœ‘’têzúiõB…È¥-E,ßûßìAWYÂQôκÖÕÃ/FW¥&ñC™ U|Ö’¿k³¿n ½_C¢Hˆy‘ºÌü²o?âSŽè_¨AïÐX©ÚW¨%’4´ÞlüÆ/«g_i“¨bŸéuPÙJdÙU*|¥o¤‹o²D”oAÍ>Â)]Pª2ùú.ªÏšÎÑvócAî Ia%M£it;ôÛù¤ê~æ\F{¶Næ¤,í°4!ìZj«¾ÔéG´=à^.¹ î \غ—].|¿îÄïá«Ü…GDÚP¡O>[šÖÛ‘GL®Ž(`ÎÇø:Øgz'²Þ©R¦c‘Õ±Ö•ðÓÝò6ZÖ„˜‚ nïi‚:1úïî
+eBÃp ¨ŒQ§W@ÆCR¨ j298¯¥ºr”H£ŽÀB¯¿¼NµWðÝ9Ê¢-ÅÞFä©”C)T›<(èËO&Ò •¡i)==߬·ý†€t”ƒÃr>:°¦vŠ ÛÅo¿°wÐl²’Ã…ð.2Ú\u.sšŒgÌ5¿’o¾±¿»,¼B]ìæçõ‡ßþó²ýøiMñA
+OÛµ¿¬jšþ©¬}H¬µ' Œùá#¥Òh§cq%YBPÁЄõ6Gèaíe¼øxKm=ÚR´•@ÎÍtÓ+9ÖtcÑÎsFæ*Ëøô£J &¶*}ÇÁbœÎ  °\ @e˜‚7ô>Öy^
+Q²ùï¤;It=Î Oï`–¡ÐkÛ/Å1aOíWÔV瓯ü¾(º€Ž<´
+¬Ð/ ãRœÓA
+në_­><qGBƒ1çúÁu`3Q&ž°áFK¨÷ÍÂ{¶ø „ü.LE?ü@ÁS8Š@üà,IqÍ3\lH0< ¡8;ç™C’Ùe€ÄÐÍ~s‘Ø$íÃÅD‡jR¯Ÿ!þ·;SR<\ÇÅC˜ÏVìlCÌ–å·gË&‘v‚ímöOîNG½ñ0Žæ3óLîæ>‹cêYFµ——2VÆÑÚ¿%†ew.ñHûúôf]wðc†½1Èxiñå°¶{¡ÍÝaæRå~Ç£WëçÕú‚ÂÉ|´;ƒòlØÍ…@^ì3Z
+†Ár ”×Þ™’hÚV¿—äP4V9L88ïWg‰æ5¦3é4Hõ“NãKoáq©áà½Ï¡ïÓÔ$Q¿}GüÔ‰¸—Ëÿ!þò”< ë6Ò¿Þ¼‰ŸEã®Ü£°Nå|Q‹ N0ˆÉýb쌚ØTi@ßl/TowŒå›íøÄã9ÞNypßÛ¿e­4“ÛetOóù}P‘Íêùǽͯ¼ô“Ž+~Cñøá G“ù"‚è,¦~òýŽ÷‰Ù‚G'¿z>ã-0ˆýûêÅôqendstream
+endobj
+830 0 obj
+1781
+endobj
+831 0 obj<</Type/Page/Parent 635 0 R/Contents 832 0 R/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>>>>/Annots 277 0 R>>endobj
+832 0 obj<</Length 833 0 R/Filter/FlateDecode>>stream
xÅX]oÛÆ}÷¯¸¨XŒH}Ú@dKŽ 4Mo¢"¹¸ìÊ\I“\•KFñ¿¿gvIJ¢4)nÓ‘»3sfæÌÙýã§þú4¨?¢(½¸]\Ì=o2¡ýG¾ÆzøLÆøõ½€rI+^€gØ¥ùÀÛ/ﱩO‹ï:šŒiÛz´ˆ:"ŠŠûD¬Í‹Å§‹—÷ƒêÍÎ ™"WÙšôŠŠ6"Q!sC¦Ìs]f±ŒiùLæRÀôOŸdaè¿¿\ÙæÒȬàõ0€· ZÕFzÔõÙáEÜ1e´!aè7
;¥‘yøâŠ>„ΟL!
¥3þåcØÉ4m…1x“ü²UyóPd1Ñ,ìÄʈe"ãð…G.”¨
@@ -2420,615 +1873,459 @@ xÅX]oÛÆ}÷¯¸¨XŒH}Ú@dKŽ 4Mo¢"¹¸ìÊ\I“\•KFñ¿¿gvIJ¢4)nÓ‘»3sfæÌÙýã§þú4¨
µn?u ;éyjþe'öDý>œÖ1êöo„t{"”ä‘n‰±nL‰4,¦ïó×oiƒ:ÊPaK‰~ij,æS¢kžEÅFhÃúÀêt#B¯ˆ§Å¿~Æ¿ÒS÷p‡vžt
Ee(1´žÂÖ-¨‡Z´÷q"ïwµ°ó•2hÞ˜.—2zz¾t¢šÚé:×ÚW¶‚ÝNÁ©ßmÕtVm‡q
-Àòœ É ƒ{i—®–gΠŠoÜQÉ­@˜5@ø®{â<‡s®Ý½¦ °#½µgsõæííª<Ù#wòG>n Ü}ßì€WíuÎËûkòq5±â›¡`l9ûÛà]{4wÍD?ÏïiNäc&Ÿ­Ä]:@ëV@ÒpØ1§X‡q<vÆzU%¥Á¥L=B·Ú¨/5ëå'K£ mÉ–o®Ùo††îv%Înˆ l]JSë‡%†l©ì“¶å†*«“€‹/ö2éÎ]
+Àòœ É ƒ{i—®–gΠŠoÜQÉ­@˜5@ø®{â<‡s®Ý½¦ °#½µgsõæííª<Ù#wòG>n Ü}ßì€WíuÎËûkòq5±â›¡`l9ûÛ¿ç]{4wÍD?ÏïiNäc&Ÿ­Ä]:@ëV@ÒpØ1§X‡q<vÆzU%¥Á¥L=B·Ú¨/5ëå'K£ mÉ–o®Ùo††îv%Înˆ l]JSë‡%†l©ì“¶å†*«“€‹/ö2éÎ]
endobj
-1067 0 obj
+833 0 obj
1836
endobj
-1068 0 obj<</Type/Page/Parent 794 0 R/Contents 1069 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 316 0 R>>endobj
-1069 0 obj<</Length 1070 0 R/Filter/FlateDecode>>stream
-xUÛŽÛ6}÷WÌ£Ä2IɺX ¾nd“M¬¢Š>Ð-Ë+‰*Eaãý÷%ßÂl·k²ˆÎåÌÌ™?>®I9˜ÇƒU< NÂõ¥2<puxa€ßÌ ”€*˜D‘ãŸDQèx½¡=\^hi¼&A¼C¯>z‰ÓNL N†õsú‘7z#ô(Á'ˆ(óÞŇÅxP{XÈLVq^Š)K$·‘èEÁ›f
- /·|–$²­´¥×æé²V4šY’§<y’»]ožQ/ðB×÷K‹'‰^<C/¿ÿòœXj&Òÿµ¥L,4"Ä·n# ^-ö¼ÊΩŽ×Pj°Q1«€Ä{¬‚,
-ùœWä ð
->.?¬ATZQ¤ mŒh+õ4jßBƒÚ)Բɿ°‚ÅÄ (š©‰ê¦d#6Áê¢×´šâx—%\i¡Þƒlïj!ëB¼O“»ºàyuÝ·T™•Ú+%Lóï?qSß{¡x‘¢ó`Û(1Àg©¾É„E„—ÎWËU´ZÏfKwù„zÄ[­¬«µÊK®Ž÷J¶õ‡%¢ÏµT¾ë¤[t^Ó»…ÕÒ{cÇ´P×´þNÔ±ÖÿÌë&áק¿°Ÿ,»}'÷%øQô©-·BM»Ë•Ë÷*¼2Ë«Í^ÅÆÛ¼oy³·<¼©¿³<=‡Aˆâmãö-0×Nè2G¶`/K±ÌƒTGLƜdzÑ"“ãSûZ™½0{7 „Ò‡¶ÑçÑüOš¨ôµ–a.CB=Ÿø‹åŒE~Ì<[•ºw½è¦#^¤YÊ.\Ê[;’E*¯# 8{;dlú½åNê9È°e‰sߘ„z{'ú¥†ƒ¿Þ˜ëâ
-\ÃPêøS71Ι .Zݾ0Z@l¬¥2i»´à™7€Ì¤¡­S®EŠ.εs{:TbW`±;¢Û˜
+834 0 obj<</Type/Page/Parent 635 0 R/Contents 835 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 280 0 R>>endobj
+835 0 obj<</Length 836 0 R/Filter/FlateDecode>>stream
+xUYÛ6~÷¯˜Gˆe’’uX >·²É&VÑEh‰–å•D•¢°q‹þ÷%_a¶Ûµ ˜áßÌ|óç€Á‹BÀÀõ!)óx°ŠÄ C¸ÞT†\F^à;sC'%`‡Ê&Qäø'Q:^/Ac(D—Z¯ DïЫ^â´ˆ“aýœ~äÞ=Jð
+"ʼwña@`D1Ô2“Uœ—b
+ÄÉíA$zQð¦™BÃË-Ÿ%‰l+méµy:…¬f–ä)Ožän×›gÔ ¼Ðõ½ÀÒâI¢×ÏÐËï¿üçß–š‰ôm) ñ­ÓÆ‚W‹=¯²sªãµ”ìFFÌÇj ñ« ‹B>çUy¼‚Ëk•VG)h#ÚJ½ڷРv
+µlòo'¬ G11(Šfj¢º)ÙˆM°ºè5­¦€8Þe WZ¨÷ Û»ZȺïÓä®.x^d÷.Uf¥öJ Ó¼Á³ÇOÜÔ÷^(^¤°è<Ø6ÊG ðY*„o2aaÄ¥óÕr­Ö³ÙÒ{îd>¡ñV+ëh­ò’«ã½’mýa‰è3B-•ï:é×ônaµôÞØ1m#Ô5­¿u¬õ?óú‰Cøõé/ì'ËnßÉ} ~}jË­PSÀî²G%Áò½
+¯Ìòj³E1…ñ6¯Æ[Þì-oêï,OÏaТxÛ¸½@ ̵ºÌ‘-ØËR,s…Ä Õ“1ßcÙh‘Éñ©}­Ì^˜½BéCÛèóhþ'MTúZË0—!¡žOüÅrÆ"?fž‡­J݉»^t Ó/Ò,e.eÈ­É"•Ž×Pœ½26 ýÞr'Ò#þa!Ëç¾1 õöNôK ½0×Åfæ%¸$ÂgÿUÀÆÐÿ•dÐÍ„Zn Á%Ï àEÉÉF™q•šÑ{ä Ÿ?ÿ-¡CöÂÿ]¸†¡Ôñ§nbœ3A\´º}a´€ØXKeÒviÁ3o
+:6F‡~ÇûXª/ƒµNXendstream
endobj
-1070 0 obj
+836 0 obj
860
endobj
-1071 0 obj<</Type/Page/Parent 794 0 R/Contents 1072 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1072 0 obj<</Length 1073 0 R/Filter/FlateDecode>>stream
-xWMoÛF½ûW |± ÈŒ¤(¶“[œ´€‘SXEuQ,É¥´ ¹Ëî’Rôïûf–¤$ª@QìÝ™7oÞ¼Yýy1£)þÌè~Noï(«.Wo~|Oó)­
-üæîþV9M“é?É®?mTÝhO³w =Uµw[SêÝ.»&c)¨*U7«?$Êl£Ü¾%sĹƵYBÏ[í·FïÈÃÝxeA³Ywe~Ï^¾<’ÕÍÎùoœ€š\RTél£¬ ¥{ÚmL¶¡¬4Ú62eIe™|®4¡áD•Ê6Æâ*@ª>æ„ë”ngo#Âàn3U–¨êRÊÒà2!ZmLˆÑ2gel8Äl6ª!å5y­ò=5 ÐT˜R“²ùçÝ؆—hr¦ÙhÏ…å`îL¼„#=ØZào(w`]ƒZ²²ÍõH$HìUCYëñ¡)÷¤Rà
-ß‚Ô¨cGbÙ„Š7Zm B´;PeIÜ•Žl\úälaÖ­Wq–©æ_šØ¨@©ÖvT': LîdT€à*M/,ÎäÉmÐÌzB%Id~—@Yùõc/¼ªåóŠX(d
-á¼®lUá]EKÝ<>=¿È/¥O_Iå9Žð9Z´6ãK#Ä™›ØLèç ¹NE¿<-_:F…+³Þ€*sðæ` ¤+ƒÐÆ#8¸Üƒye¿Þƒ% &1:€yC¸Ê5Ù×LMßÑUÊò20¿7ûZC. š9GŸD²<)L[ªG9»A‹·{r,UÌœ‚ê~D¯ôå‡Õl‚律¤ÅÃ=>ÏñCQô®ÒûÁâ]làÁW` ó„†~†¶®g}ʹ;ˆ^¬ÛQÑ– ¾»ÁuÂ8–´TèÏD1Û*Íy>¹yª Žx´½“ù‡Ö]ÍT±eŒèáv†*Mp¼ˆCþzôág¯×ï^o^oÆzúŽö¿{r°›~æ*Ø\y”Hyí][ @ΨRSšfçEJ‡ºzªrWqÓK·â\®0dÞÔ0GTÊ„©­2%Û(zòÏÏ_>>-“æ{#á+‡¾ËŠ9Éð/¥1*ëêë.u•I_Î+”6XÔ—(.'C¡
-2gÄc<ª­<'Æs‡ðF˜áà÷ý¬r4$}‚]ù¼Ã±Ï‘ ì–=Œ!ÓŠŸïa½hˆa ñL¡Ž=a—Æç'à‘b¢¤¥«{×ú!#|ïÔRÆ/yÞ…Ü£°qm™ËøÝtÞ‰²Óø”ø±¤$
-[³(™ÍRFš%9ÖúrEŸE["ÐX£ç¼NˆU-¯Z‹AÔØð´QàÎYÝ g¤úl ±y‹â' n­|^ò
-‡Ýì68}Gêr5éªå9ÌI‡O b
-ÝË=€›4ÒP·”Ç|ÿz \Œ‚ìòÐ󾃅È- ¥-/½çýl5¿B”—'A¨uf
-ÃÏ Y§½“7~…P—«/ò¬9K/
-:= Uãyd¾zǵ:±
-endobj
-1073 0 obj
-1463
-endobj
-1074 0 obj<</Type/Page/Parent 794 0 R/Contents 1075 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1075 0 obj<</Length 1076 0 R/Filter/FlateDecode>>stream
-xWÁrÛ6½û+v<©=#1¦$[v.ØI'>Äucµ¹è’ ˆ˜$”¢¿ï۩Ȭ›ig$Àî¾÷ö-øí$¦ üi9£ù¥ÕÉíêäÍï7/h•ãÉÕ5>dt]\\Ð*=‹/£yD­MJ]Q«-;ol}¾úŠ} Šã°o:[bßÙ}NÎVÚ¦ÞPfµ«õ´³í3ùB×TØFç]Yîù+•vÕUB¹)5íLYR¡Ë†ö¶#ߪôìjYÙ„øѪݓ¢L'݆S¸ i<fºÔ[]’ÍiF¶¥9åø?7uÆ™ôû]DïJg©¶^ã\ååð´k[]{JZ»sÈÊ8O맹ÑÞ‘ó¶Õ䢿{>¸â/j”€”‘bÖ†³¢Lù¨_5»ŠÙ³‡Cl““ñ/AâœQþ„óªWØ®ÌÓhRà¼%¿o¸MN·[ÝR­*<t´ÆŸ§Ÿÿþð)¾’`¥jµÁú@â£r|Uu&4 û°™qM©z¶À«¶Ê”’†+1.ð üS£mƒDÿ€³c£C©ê€32Ø£zH¡¶¡˜MiUÒé¦Ó¦ÒÔvµ?E`Ê‚÷­*M6ü~<à³®t•Hm=³÷w¿PjëZ§¬Y„Äæ×è$2ŽÓô$îDÐðE焪C*’a„ê‹\‡œ¶Yn8RìzX
-ÉB¬µÎt6&qŘ`] ²^2H\”Áövb°êG
-CXäQ)÷ÌÎtÿH}6ÌÄ®µÁúÌ5:5¹ÑcwÆ©áFÍ™¬Ó!TâªD(^Ÿ3V'pnZÌâèš×K|žáæc£Ÿ__~Ñ-{ ËR¥­u°¾.AêŽÏ~Åí¿ ÉµºÔ@“|RU¢(Žn¢x¹>SeS¨X¨P‰Ýêõy¿ €W%,¸®IÂ1A®®ÅV`Jø⺦±­8ôˆáV7¥I•hƒÕömý"mJ`™j L*H-µ¸†.‚Ä]èkÉœ„,TZŒ€nÞ6XŒt‘ëÝ$Ó.mM +§Ì6Å}–kå;€Þ5,¶Ìä¹– ƒÜó‡c—Xñ^ý²Ñš³¦ÕÝ㈦§Z1åôÊEš”!„‡´¶£ÝÁ\’a‰9›ç&-<uÅê¸
-$ÎN Na[ð˜/÷OÄ“F¼äÅo *øTôËx†=h{ÿÇ“L%÷/k(K»c¯büŽ:yÕ® ã ŸX4*̬Ȩ²зNãF
-endobj
-1076 0 obj
-1726
-endobj
-1077 0 obj<</Type/Page/Parent 794 0 R/Contents 1078 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R>>>>>>endobj
-1078 0 obj<</Length 1079 0 R/Filter/FlateDecode>>stream
-x­X[oâ8~ï¯8o¥` ·G:‘*m;³m¥}AZ™`Š§!fl§lWýñû_BЕV RpâãsýÎ%ü:Êèߌ.4<§|ytýtôõéè´yI›‹yÆÍ)]]õ4º¼Àòâ¼IFÒ¤§t6:ëŸÇìlÐ…-ðÂ.Ô0úü Œèi¡çò4óÛ§ô”wèß?“ÎÍÝõäääéçÑ)õ2¨Ûï³?ÇV׉%Ö_âË›Æã¯1£÷DIÍesÝ  ÷ƒ¼zÿísß–:¶š–ÒÁ£û?‡µú­>í?Ô~êIªóþÁ'ºrÒìÓ#î ÀõýaðŸþ7¶Ô6¦}ØCžMô/kßøħÃÍ£]6‡£O&Øììx=@®ymÒs®QY/¶Hv4½pÖàŠŒÁ•s?užðí0æ1­°JIÅÛ7´£i´²ñ3éüq{ÿRøó·eƒ^F½Á9Ê ²ù‹.­²N•Ï¤ç4¤àgK“NÖ¥A—†“ÊuYÊÜÉMßÈ­5=&z
-H»ƒ§Ð×F¯-~'%ÁT9Z«¢À‘¢NzàXPÀÙÚâZǦ.-áe;ò#‘¯*ÊûË‹Ñp“©O»^2ò*€„Êнt×·ß[2K8з€-ý¸ ø~c›¤Áž­xLµfÄU«.ÉèS
-endobj
-1079 0 obj
-1623
-endobj
-1080 0 obj<</Type/Page/Parent 794 0 R/Contents 1081 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R>>>>>>endobj
-1081 0 obj<</Length 1082 0 R/Filter/FlateDecode>>stream
-xíWQoâ8~çWÌc{Jz:¥=UwÛö¶¬úR ™Ä,`wãÔûõ÷í$4ju½}:é$ljí™oÆ3ßØßZõðhRHÑ®5·®æ­^w<¦ºÉÖxéQ¢ŒGÜŽº!e’V˜Šõ£AwìG‚ó°;¨‡ƒaµ(y²]5èCwÕ@ÇÙõ€‚€æ+@ŽG4íxæщˆãLCÂ¥"—1Ò<¡<‘t+óéÍÝ)±“DwŸÿíóÝ—û_ƒé/]¢y’7tÚשÉeÓòÅ.žéHÕéük«G ³æñÉNðZfú`ð|:¹ —O§µÊÇ›ÛÂУj´VüLsb%K­°ë…†C8BïT¬ábJ¹V{i–^¡†zHÍåvkÅç‰È ±Ý[‰msòJg cL±T2§-6RÅ©Z“ OÖĉRº
-_°pø ?X\½µ_c»í/fõ\Ú·PûjÁP1£i°M<Ÿ¤D§‘°Á‡ ßÙXSZuD‘':Ksñ^Z¶4–¾jJîpX =N˜@BÏÈðœ
-¤¤é ç{ª8nÓŒÀ9mðL×ÉRg‰Ö1!C„©Î@J‡‰m¤l$¸á©KäG»t¾§f§­’C}/!g9Zm™ã\ê8¦°‚"}(µ7©y0\= §/ó42VîAŠLH\EE†švµÑA`p÷ÑØoPð6m‚¢‚ýz:<2©2Íóêqæ×…çm&³j‚­…µhöœå焆jØ•¥ ³\Ð&¡b¬Ð¶—n¢°¢*} —º£/Á6×yõ>DÑVÝÐùÊœŠº|ý`®Š@7Ž/JÿyZ>Ný7ûÌ%Ó€ên%šÃ ÀKþß‘bðaW~WDõa-ß]Åþã¤^RòÛ¤Žƒ\ÚžÒM¡– ­¶¯$Gôón¯ë sPئe‘ƒžsê7Yþ:UPþÒ¶ÄøÞáÙ×'T&*.øÔÏ%
-¼Gb»Â?qøêîÀè¬$;SÔ‹b—ÃUÓŸj=1ƒu=VêX^¶Gr\IDŒò†"-.]ÁJi£$U|0ÍšŒ›ÉÞ£f¡d™>Ñ«ŒáJõŠ‹-¦Šœ%ËceE›¯ùìzìï¨ÁpØ hxáƒøaòi:¡ûL•QŽëLTðÊ^
-8":Áp„éQˆël|œwû]ž½Ü↛­Þ|à©{›¶Ó.Îù.ä¶þQVÜendstream
-endobj
-1082 0 obj
-1265
-endobj
-1083 0 obj<</Type/Page/Parent 794 0 R/Contents 1084 0 R/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>>>>>>endobj
-1084 0 obj<</Length 1085 0 R/Filter/FlateDecode>>stream
-x½WÛnÛF}÷W ò§°Q²%;@ رä!J[ -Š¦0VäRÚ„äªÜ¥]õë{fv)ÒtÓô4Fhr¹œË™9gÖ¿%4ÁOB‹)Íæ”–GW«£›ÕÑd|~NÝ¥ÞàaBg‹s\Oϸ&S^©5åü îaçpÁþ—o&tA«¶ç°µÊäõ„Vé1}éßrvwùáø«/N·WÝíëîöZn_¬>Mh4MÆs¸8¾mÖ•öÓÎþrzwÕ=áùF±*××r½ŽV$ÌVúüéý2éâKºø’»C|É]ˆö“»›~¨ßÉaÖE ¯»'€
-9] B¨it1püªeâϛ®Uá~Á©XmÝœ}Àê,jhO” 5вf·³µ§¯i¯¥åÃõë¨,z!`»«õ½±°7_Œ“m' ìT ™b™Ët®šBx ó€ÜaP¶
-¯ª=Ù"Ã6žÑü Éà €à«ú d Ë°‡þo@%×l6Bœ‰íf·©¤‰qý×P„éDpárO…fžpá±4ðÜ%CÏ+ûœË¢0'°kFTÔw¡çâ¸{öüã/A~ü,(Ä'­¹ãY“„~ì·Og>oðR×HZ+¢*O $B(¶¤Ãle‰de8¦~Biâp‹l°,Uï—7pÂÍ"ÄA¯--߯Zäè_¤û˜–
-Ä›Ôì8Ÿp&€‡ž=¡»ugãI$òÆ7¡æPÆ[q6ú&ø{&©
-ô͆¾ðáE%[ƒS&ÈÙo©ÇÃ`à.mOrŸQ>ör:ððñ>´”Qã–zö”æÂÈD{êÔŽã1÷<Jt2_Œñ·ÚbÎŽ·—ï®.éÛÚ~äÒu¿ 9™QØ>ZLñ']vüå¹yº8Å4–Ís¶€)ýÝÑ‘äTËendstream
-endobj
-1085 0 obj
-1519
-endobj
-1086 0 obj<</Type/Page/Parent 794 0 R/Contents 1087 0 R/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>>>>>>endobj
-1087 0 obj<</Length 1088 0 R/Filter/FlateDecode>>stream
-x­WÛŽG}߯(íKp0 l¯´ëK´ŠŒ7f¬}ˆóÐ0 Œ=Ó»gLøûœêËÀLXG–bKXà:uªúëÅø;¤éˆ^LhU\Ü%o’‹A6£ã‡Ùà Žøs<›òç¸?&#iÍ7ð3ÌÔ8þü혆CJÖ°>™M)IÝÿ(Yun×¥4Tn%=ÞÏd¥ù†ï[ai)¥¢•VëlS™ÒAWTT¶$©,~ÀQ’Ès*Äj›)ii'L™­²(3µ!­œY%˽6_ž%Ÿ/Ô¾èà¿#`àÄö>+·î´HS#­%½Æ×ÌžÕ'º_sæôWÂ!A Q,E ¤Kë aeÎËoã Ý?PtèOÓåƒÉ
-aÞÅ¡q {2O}L’._iU·,?%óÞÍܧۻy0ºÔ+ÛÞMòê¡wãàÓLäzc9ÆÇL¥zoéúŠ42 ßæ ÒM4•™ˆ–+ŸD(—î$\³˜HÑa»Öy®÷\šå¢Öq÷ÏM®—"ÿ ¥_•Š \U[,û\¡–o@‹Jÿ¿>{UÓª7š€‚(,ìÛÈ¢—t£D!9¯c„¿ú«GF¯n%Xqî
-Y‚"©¯ATo˜YÒL6‘}f¥=ñÛ‰Ä@çº vDs¼û¸Hhþ>¡»7´x“
-ÕP0¯wÚ(‚
-ñy’g…OÀ ^䈓 —‡ôl’Ðw í[]P®W‚G´Ë<\ÄxE}ÑÕȬ•«oÊÀÀ­ø†¤cw´Æ{˜<Û7FW;Ðþ­+ô*3‹ãáàK]´¼6Ã#‰…"ÊÃ^W½ ˆPÈWs¦)ÕN»T)ÁZãhÀ‡ѳOß2°ò‰µQ¾/ˆÀz‡µ‹MÀÛGÙ‚Í«C!¾`
-· ²Ç‚e@×,îCdzå÷/
-šÙÖèðÃS‚å;žl¤ø½ƒô_è×ïÆÔÏ‘tŽÅerŘ!=wâßO¦uÒùï«K™{`ê}­2#ÛÝ6——]71B±O0NkÂJÅ/L^Vû(cn1X¡i±éùhÀÙ„¾o×%­» u E:n"â®2–òZžY´µ%·zÅ=„zr~êÔ³œ±m/%K‚¦ ZÐȥƘCÑ4B㹧º²gåOÖMY[Amm´N)K¥à‹„ÐÆ`rïV=j(¾;Z·Äüÿ%ü,¼8†“iH“ë§ÑâöÝÝ-F³þŒG Æýªb-Å;T+Ž®ç÷¦#¼yÓÎì=ã)oMîÚõ”maãúãâcŠ
-Oendstream
-endobj
-1088 0 obj
-1553
-endobj
-1089 0 obj<</Type/Page/Parent 794 0 R/Contents 1090 0 R/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>>>>>>endobj
-1090 0 obj<</Length 1091 0 R/Filter/FlateDecode>>stream
-x½WÛnã6}÷W ò”jÇv|KшsiýK×ö¡ÛJ¢lm$1©þûž!)EVât¢M'¶†3Ã3sÎLþêhˆïÍÇt>£(ï-ƒÞMÐ z})7x3¤ñøb0¦ÉbŽ¿'“Á„JI lñn
-ãwŸÌ¦çƒÙ›'ˆ‚cݼ ÄÙí.(HÎ áƒØ>R’ÿŠU.Ò‚r¡,ég*Ô§à[oHýÇâÆ0S‘È^íöR1|.e"ËRÆßc¬4eòEfˆ<›²Ã³Û FœsDýñ ð ‰k…Ä ÅŠÌ6Õ”¨’r¬ÌV¤
-Ik‘‡‚´,_p UÑ–tÒü@°6[¹§]še´%þ0[g¢ð
-¿"2$4‰÷=Yg]8O(•~EߧYäaLð h" —>?’™ŒL
-Dð£(MõL¢€)'Z£ßNRKS§¸M7€©P~i†^JM]vXoU•Å€´€ßý›¸º‹Ð*¡½ªh+^fA÷Ú$Ú¦¨!2ä¬\Õ\4¶Ü¥zË7û 
-|®°n#¸ŒS-ÂLvòt’”*‡§Håi±9‚<…{t’1lÁ %ŠëÆïÔ3C© wål2ŠìOX{Œþ¼Xçá REBIšIú‘Ÿ¶xÙO]çü[B%n·>"yÝ°r¢V¸XšÆL!NV¥ 8g·4Bß'P¼Épa/ò*1£é`> µG}·dÎ0ŽÜ+týpw¹ºwpÔœ‡îŒçÌ#ß%‘Dó™6Ã5÷ƒ /i3¡ÐC×NÆš>È+m¬d Ä-pÞ²®S¦C!¬éMË=Å2U9ˆøX¦¹(÷uä+U˜š³:áz.£܇¨€ûºQÖZYÐBÞÊËoMZö`ÙƧ|Í™\¿b£Ž…¥O”&Ý«•r“²–£Æçªh÷Ò,Wk²©~=uuùe´üéë'§”_V÷kÔ ^ELÊö8=^_u™}‹¬y59]µòÌi°Dƒ£†kɵŠ_–¼¹°ÄãzV"i5õÃ{
-¨=±¶½ám[ŸÁâF±‰£{'øòSC÷ÿ˜ïÿï
-endobj
-1091 0 obj
-1223
-endobj
-1092 0 obj<</Type/Page/Parent 794 0 R/Contents 1093 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1093 0 obj<</Length 1094 0 R/Filter/FlateDecode>>stream
-xWMoÛF½ûWLur
-ô`£ ` QZX…PÀ—%¹7&wUîÒŠþ}ÞÌ’²´VŠ"ˆmQ»óñæÍ›á¿gcáߘn'tuCy}ö°8ûøyFãkZ¬ðÍÍþ(h4F´ÈÏÇÓáÝ>»&7vM^Õ™¢à(ÓJMµòA7ß`ãšÆãhãrr çË’Ïå®Ö^âiÊ·õºñThܯÕe;R–t¥ó`œ¥Mãrí=µžãŽ*rxóC¢O*/÷Ùùˆ.ÇWà ;ݨüEÊ ÊXOŠl[gº!·¢jTÍ=mK{ïø¬\ê\ÚæšžÏ3£üóÜ/äK×V•êU“±œNâ·á=ì`x¥Ú*ГàÕz  èU7;ªÜöвŒµÏùPo€9úÖ±Ê\‹Ÿvç¬Æ×^;Ç“›!WêüqE;×ÒVÙÞ®nã­RÛhÍ®ÛÀÁ£~ÕÕ€Ö•ËTEn#¨ãž¯³!à[qÈÞ¬K Aì}÷`?†>S x„äÿ–r]]ÓV
-endobj
-1094 0 obj
-1575
-endobj
-1095 0 obj<</Type/Page/Parent 794 0 R/Contents 1096 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1096 0 obj<</Length 1097 0 R/Filter/FlateDecode>>stream
-xUMOÛ@¼çW<q!HĵóMo ¶h«DâÂeco’{×Ý]7åßwÞÚNœ
-½öÐßEY{ÊÊT*Ð9‡×Ê“Ž"Ë P#º·›th]Õ1Z+Ã$}cµ¦ñažwÌuê-ö橹j²jCÖ” :V +÷ž¸í³VcZÍöÄʸÆ:"*,Ñy÷"ïF©ŽÇê5
-xyÏÛ„p’×
-CÜìŒ}æXÓ³øŒVÂÁȯ®¢ÇþÚX’ÿDQ"‘?H
-ÖDAþ 8¼=ðØŸÀ¬e&½P¹ë’9Màé·Ü=o^ÇÉtñ«/â¡‹ë»›kúeÍ“D"3iUà}'3¨«uYÿÓû0žÎ£
-{Äq#úïÞËü’˜endstream
-endobj
-1097 0 obj
-905
-endobj
-1098 0 obj<</Type/Page/Parent 794 0 R/Contents 1099 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1099 0 obj<</Length 1100 0 R/Filter/FlateDecode>>stream
-xWÑnÛ6}ÏWÜ—¡)(–Æé€=,ÁRØ’1—¼Pes¡H•¤¬ùï{.IǶ6 CÑÆ•ÉËsÏ9÷Pù~VÒ JZÎiqCuwv·:»zøLó­Z|s³¼¥UC³b6Óúü~#ú •7=‹®ÔK×Z× SKRÞÒ\ýk”שÆå¢,æ¨rŽMeA÷¶ë…SÞš¼òšÊ2¯œ/yÝj#sq/ݧ ^zZÝ£`)ýbQ­•4¡ Õfð¤ZÚÙ„“ÜN™5¯ò¨ZRaÓÓ(µŽ+ýƺa´3º, £“BëÕ$ö®Ò;»v¢ó6"0|äE'ù«`k«„¤Îú@(Ñ(Ô[¡´¨t\”öƒ)jž'Œo¥›œþ^Ÿ›åNÚÐöcq¢‹Tˆžÿ¸CsÌN‘kÌo
-ÞœM<ŒÂDìA’X eðÓÛN† s£Õ›$A+.ÿÒ¾¬s5îÌDzFž6b °–åc' ‡ª!D ÖLÐKA⟬ ×Π鉿¸c•:±KBT|2 c -xkT f ì;¹ôzî‡zCÂÓ£ •ÔëGp2Õ.‰
-Š£«öv£ïƒ
-r“ 
-¾j…çI‚䆞/H耽ë )OPvGwÝÈ^šÆ“º€Ñ6vÓ†ž%vƒmƒEák ÅaÞÀF%ôMíAz´[ÌÃ#ˆNPæq…>L´
-ÕðšO«'=䱇Yî
-&» e(Ú”çDÒhÇl~%?€fä…j½fC¶¢0úd‘œ-x†?SÜe46NNß׌<ÜBãZ÷<— “Äçl‘0¡¸ò}Á4•t;y:9kVK0'P¹šÈ$Ê ªp›Qná÷´>ŠòÛê yI×ókDÊõíŸçøËÓ¼×2Gãâó,í!`‘‘ó‚žzm뷘Ȧ¢7¦çœóó Ín•™’«‡„gÞšreÀ¤ÅXáÄHéi-c vlÆZg; `N[X§§5JÄIJP\¬™ˆ˜ýê‰0ˆ9<d!¸-`rmß[£|P5W~ÃðB£$TBÄFh²g \"pAÄŒ1Á7,¨eYØ΢®%Ps¼ghl ì‹ñ%ÖŽÃâˆôC/¢ –/9.a »n粧ÆÊïæªÖÖO-rLЊ'¸ k6Œ4¸ ÙÇwe…
-“88“æ£BÄÊV :\ü uŒ¡¹_Þ¶<RP##/©Ú]ÆO„[EQÊËöjà^ÇÈ©ösr秣«=_OÉž~¡¡‰§.Îë^˜Œ]‡ìKfà % t_È6väàCz‚ð”àÚ
-endobj
-1100 0 obj
-1536
-endobj
-1101 0 obj<</Type/Page/Parent 794 0 R/Contents 1102 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1102 0 obj<</Length 1103 0 R/Filter/FlateDecode>>stream
-x•VßOãF~ç¯åå8‰˜$ä¨Ô¸ã*Ô£\K®Rµ¶×ñÛëî®IÓ¿¾ßŒm’øN¢Øëùf¾ã¿O¦4ÁÏ”–3ºXPRžÜ¬NÎ?Ïi:¥U†+‹Ë%­RšD“É„VÉ©×!˜jM!×T+§J´£ŸÞ¯žqìÃë±ñlÍqð´Ð/º˜‘­ ›l<ýLÁ5º½{_äõnŸÛ¦HÉ×Z§”Ø*iœÓU •$Ú{
-–2Sh|Ⱦtš*p_YÚªØÑÖ™t…ÛÎÈ7INÊ“ªëÂ$*[‘×î…±ûG=ƒ˜ÐxzÍèÓ©ÑQw©}>êeªîùÝ~»íÊ÷§{“8ëmè!ËL¢ÛG<½çâ ‹Ân=%…AÜÁ ¬Ó*«œÿQ¢L5±µA‹6ã{Ý–ŒøØíê<Ї«%þÎ/ùï ¿CÖÒvES iû°hÛÚ7]D³è"¢Ì÷]¦6ºçä>ÈxÆ”êÚi K§ß3Ä28}Te¬€³B_d<æŒâ­ªDª{:ms]AŽpLf@ „YG¶ÂÄW¹Á 0!LÛÙ¢
-ñå`쯞dßB4:žÅõ‰›6àö¦FýFX*kXJûÄ™ˆsȱϖFqÄ!£\ÇÃüFp¡]AÈúï,øËÁÞ:FDά󖞒ó¬uFj@vŒòp ;4 ® ¬Ä~–X>«$”j„b
-{ÈçÆæHrÎ>ž<V´Ð-Ö–#оã4F;v(&Té°µnóÖ°:c%ýõÛçÛ/×rÂ2£¢Fd@) UzæKȃµ:_Nµý
- bWF\é ƒpq[›ÁY2Iùä ð6·Pk Ú-²Bùéݬò–Fê Ù¤gâæ+ðúaÇZp`½êrAÊøbV¨+˜@±õùçËîUzºXFSZ,'í[êãõýÍ5}uö™3ã“MÞ×¢z®3no/gxYOOÿÿ;ß|q-ñþȇ'3~$TþûÉìÚëendstream
-endobj
-1103 0 obj
-1411
-endobj
-1104 0 obj<</Type/Page/Parent 794 0 R/Contents 1105 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1105 0 obj<</Length 1106 0 R/Filter/FlateDecode>>stream
-x…W]OãF}çW\奡oB•öº»ÒJ…nE¤ªU^&ö˜ÌbÏxgÆ„ô×÷Ü;ÎiH`<÷ãÜsÎÜü8Ó_cºšÐÅŒòúävqòáË”ÆcZ”øÏl~E‹‚FÙh4¢E>\¬M ÷¬}¥šÆØGÚ8ÿh¥C¤ÍZ[ŠkM¡ÑºÀk%&<‘²YùMRy®C åñ–©M¥ü­Õ3GBÐ-U&ÆJ“.KÇÓÅ÷“/² Š¾ŽÏáÕ„zê6_Ó£×*jTªÂ¡Ÿu1&³lÊ1(¯Ð¥j«HϪjåüxv1ŸžÑªÅ³ã"^íM­mTÑ8‹:¹QôXpÞ­Ž‚!imð€;wM4µªRè³^ýŒƒ‰\pežtµåRǾTÎÆT|PHCxkè8k؆¨k`g·µÍè¦k€§A³ËKÌ¡g, áä;Wm@õ®åêUU¹°Q­k‡œ­µš¤¼©¶‚ÝçÅ †O³ñC˜Î¯ðû?˜_™¸rMc Ë\¹¼J Ø2že—Ý©z©Œó˜[çæÖð&RˆÊǶ,òÊ
-,õ1ˆ®Yö²¼râí©qÞ dðµ–õ÷rˆÉwXÖ‰•Ý-µÈþ ž1áùE/=|Ãó¥[v>N/ØqNQÚ¹³ŒLB´4Â[—ße1ž‹3úâ<ŒÏâ¦kšÊàRg¥%YŽ£ß+Àmì^Þ‚#»
-›1¶Üñè‚ ž¿NþèÍ\¯endstream
-endobj
-1106 0 obj
-1590
-endobj
-1107 0 obj<</Type/Page/Parent 794 0 R/Contents 1108 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1108 0 obj<</Length 1109 0 R/Filter/FlateDecode>>stream
-x½VMOãH½ó+J¹,#'N  Ý‘vfw!Òh%.»÷¤ÝÜíxòï÷UÛã™…ÃJ+ ŠèêúxõêU?¤4ÆOJó Mg”•'·Ë“Ÿ®(½ å'³¾ä4NÆã1-³Ót–,úÝmÈðžÍ‡å7˜_Pš¶æç“9ÌOïÖtp5y
-&s4§ÇSe¼£­u%åi”óªî|?P¡7W¸¤,M䮎Ju _¯×8RdTµaÊ+·#m%1§Ód"w\­]U*›qBËB{ÂïŠ3U{Ž©x®öð²6µ/Ø?g·Ö†I­ŽXe98RA;{FM¡ñ ­˜p÷@ü}ÇÖë=BHøß–'€‡fÓ)>/s|NðW1­‡h^^]Å<_áy•ÐW%mÙÿ  K 8j:«­!AÉNª”ÄV­ ç´:PÎkU›pF«:nûk/ç¤
-Þ-ŠôÎìµÝ hUÉ^pgêÛçc {Ïivijª6šøf¸u=}`?:v +‰kLzè_N/ßGœþˆ~:NèžUN•jÞ¿êlúŽ‚~Î^o¤¦à„`‰t¦Ôžó3ð¾97*°ÍÀ…@Ï÷ºA "AðAéYáœpÖ¡Áäßí\ÈÑØÂ5½*A°œT¹RTª-È|4’úù
-U”:B‚KÇ^H3ÝQ(‹ٚÌÑ€Ó;KÞ•ŒVyËŒf
-³<B'@¢6ã;þ*E¹
-J"ÈðåC«†˜÷¨R@ÚÑ(çAÔKì,®R/ TUU\»B)fqíœÍ
-endobj
-1109 0 obj
-1188
-endobj
-1110 0 obj<</Type/Page/Parent 794 0 R/Contents 1111 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1111 0 obj<</Length 1112 0 R/Filter/FlateDecode>>stream
-x…V]OãH|çW´ò² 7NBû…°ŠD€Û¡½ãtšØãØÛã›|¿þªÇö¼ì"+8óÑ]]UÝÿøÔÇŸOgŽ)È>¯>^È÷iá—ñäŒV!õ½~¿O«àp)²µ ]’¦”+KZŠDÌÏLiI¡°‚l,r<$‰L•¹%SÈ ‰RR¿ï¹m&ùOöH6Q¹GsK"݉ʸ3ÍÑêûAŸNü¡7Àý‡õ*'KëTxâèPèD×ÎVˆ‘Æã!ž£Éž|RT§tNþ¨Iipî}IÊ{¸ˆ9T”‰¢Hò ŸºÄÉ€‘h
-™ãÇ*þ¹Îk·t]¹xjâi±ëuÁ ZÔD\Å¥qig¢Âù€ðç×%ð,W/‰Ü†01·—[p9“ãÇ úÔ¹7W½}úŽ&§ÞäúŽNY¯É;òh™ª]¤‰Ì­ÏÔe"OÜbÁÔe
-7´‘Ör¬\¶B+«•rÑ/n¿Îî®ï—|@:^œÓõôf1½І™!(Ô"zA'9èž5Ÿá¸'™!0z<Œ´ÊÈïo?BŠüSþöxÔ­ÿœLÉ®)0 X*w ö'cóìi-À€Ç#Úò$ÌÖiPé7\¨¢@•iHA,w°™' 2I–@voF]ïYK ØÓ³WJ°«ç$ÖËÄ3=gPØ'ôG“Þ1ŒÎX6E°>
-a“Lztï¸Ï+@M‰­…ÐK RêÍžö©|’i¯n/ oÀ
-Û6•¶Ý¼r™¦Q Ð(Fï€7@£ÿ¤µ±×ÈŒl™#4Ná-±EV戺$
-YÔßY( ³|Y»}€ ©!~÷ ôv£UY@6|\Aå®å+J¶DÞ±†²!ÜÕÅÝïl)áë6‚Põ…¡´"I ¤“S!4
-XB4ÇP’ë èý(½.ÑêÑ‘œ\¹ÑæiÝ^Ž@æ7—·ËùŸ3' ¼Yξ,f7+÷Š»¢;»íŠ ˜Ã~ÿ›¾5eÀð›Æáš^!ãç‹x`¨lÅ|)#Q¦ökðT#Üæ¯Å!ý у¯¸õÍÞµü¶\ÍÞüfîºát ìòF]‡}LTÜÚ™¹ëd³oƒìB¡Ê?XÚæ0í]\µvÐöàEEj—£þÈŽŽ†½C«ý9Üð9m$ZeÄm±÷p‚š°·…òI¤Pîã¡?NF]îèz
-Ñ0dºE5ð~ðu¿yå”Iðv]§k s7Ø°^AX$ƒ`†I«zªÛOç^ˆ>éF­dB­
-F^P„âƒÇø>ì-,ÁvÜO\7qPò‰>xZÌ™,F4êŠB‰Á!l¼…é…‰Gƒ-:ÜÁñê)‚Él«Â 0Ðû3F´ç—©͉¸y Ù:Ãçy¶®¨¯&Í,íÏ<óô¹›"§‹ÏSºÓê;7¹K”ÜÝÂàœÔ‹OκCëóéh<ñÎ0¥óšþ)ýqð?ìºúendstream
-endobj
-1112 0 obj
-1441
-endobj
-1113 0 obj<</Type/Page/Parent 794 0 R/Contents 1114 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
-1114 0 obj<</Length 1115 0 R/Filter/FlateDecode>>stream
-x…WÛrÛ6}÷WlŸâL-šÝÒ7ÛrM£DÔq:M ’“€¦Õ¯ïYò…v§qìi
-ƒ0 iž.EÓ•N÷F”’öÂR¦ñÁêB’“Ö©rGº¤4W²tdU†×uÉoE™QÊËÈir{I[çºá_¥ºLóÚ*]Ú_Þ®¿Ÿ„4ˆÇÁOç¥u"Ïý†›ØJWW¼Çf•ã‡Ñ5M*5Úê­ ! õ^YÂQÕU&3þ ij:½%œŠŸ|§Ú©\9%m9J‚˜#7{•îI•Ñw’*ipD!ÊT½+^ér«vµA¦È
-Þh}µœ/ÉȲÎ÷fd,§¾S8nƒÒP{l{*Í©¶’!àΈ‚Rä-³Þ­ë?VËë뙡½âœvÚ‘Þn}|*¥c$î#ð}'ŒÒµ%Ë™Çd±Ë‘;T ¤”ùÄP¹Øä2 >¡ºK‚Ú¨> Nxƒª?…ÇC2#¸/&hõPÍ…¸GD_dÁ r€˜fe§QàŸñ88–àËÍüÓë‹ã—‹qðEíôLÙg[|â\žGI^Ýx™ƒ t.gÒÉÔýÇÞá˽k…Lך>rQéºä€Ùóˆ£ÿÙ5 Ÿ—+¢$~¾oürߧٜ®D
-ÐWêÄ Ÿï˜´;ñèñ99£p¥;e\ B¡ÈP“/¾$åda©€R!=,R¥§P¦Óš_zyø7ºÄFÖy[ûB@Ö‚2µÝ‚fóºèó¥90AXo­8Š h|]m8 ®hÏ ;A0‹åöü Q~â=¹ÍqIipo$Á…æ|l%ù4P¶dq©3>°‘²|à«ËÖ—,ùÔ;ƃñ˜âpq ¦ G'Ñ£~jDUèÓuÌ6©„SÌ-6g4Ÿ]e†Yðíô7‰ärŠƒ0HÂoo½nF†íˆS6RXíã%…´V®ûöò~þuqÍr„ç±ËÀÖ ,¢% ¢_,-#äÐ9nrKL…É°b‡ƒá0¼½<G£0Œâöaq­E?nè圼Ãî¨Û=Äè{˜}&£ãþDK&á ™vë“#ÿÐ/ŸÏ2cfÀí¸ep¿8Ö\£½·#K#ÔÅÉ{×Ú=ƒ-(â—þ-÷€\ R玑)ß8àNSró1pÝ^^LÉ=
-æÓx4œ×JÉf’SYi0ú”`Àƒ‹çê–Sö Ä"ðC#0PÏZ€iAlÓ±½g"y[èiæ(Ž›íÍŽ’
-endobj
-1115 0 obj
-1704
-endobj
-1116 0 obj<</Type/Page/Parent 794 0 R/Contents 1117 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R>>>>>>endobj
-1117 0 obj<</Length 1118 0 R/Filter/FlateDecode>>stream
-xMQËNÃ0¼ç+æÖT¢Æn‹Ž­
-endobj
-1118 0 obj
-305
-endobj
-1119 0 obj<</Type/Page/Parent 794 0 R/Contents 1120 0 R/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>>>>/Annots 325 0 R>>endobj
-1120 0 obj<</Length 1121 0 R/Filter/FlateDecode>>stream
-x¥W]oâF}ϯ¸â%‰6“•VU%]Ô|íB»­ÄËØÀ{†‡å¥¿½çŽmHP»«¶‰DbÏ×sÏ=çòõh@}ü(ŽhxNiyt5;º™õƒñ˜öf‰L‹AD£qŒÿG£`DFÒ‚W`Ûì>0=¼½ ¨O³v?Ç4Ëü8Þ¤'×+±vÒÐ èqÑu‘KåèÃãçÙãéì˯Œêµ½!9ËN0yÐíåGËSúÔb¯æ5>è ¥BÑ„R­ù²BhÓ0¢Ï¬éZ+%SGÚЫ·#–D³Ýà<à(OÒ:˜¦NE™ˆŸxÜ#Ò^qÀ÷üôóQtv è,Ž€FI£xŒ¿õSASF%¼Ñ`Pßã,¾Áà’JS]® é$ e7€Äir«ÜÒ×JZ—kåï”H¢…®TFxáÃÝ!ícÜ'´rný. SatlreƒêEªÿ,¤¬6¡åË„ ¬\Y¼ÝƧŽ· 4¢sdh\ ›§¢(¶]Úꊔ”4²Ž\+ä;ã5 O¯]4[IºÍ ¾TFO&Gn›ÏOŽ'W÷ô$¥9žŸú»„·iR/F|RçÑyÜ ¶òXo0¬¹0»~
-'OÄ»)IIG¶Z¯µqÿkW„Ýyîjò8%ý‚lÔçt(39?â<¼¹ºùuò/éEc¾Ãg¢¬¦¹ZKTPn¬#·AêõRâ¡MîV~,V’^K#O'»µN–ÌAI!Ôsûœ‘ßÖ…È2”+¿˜©ßä³E®ªE@“E]´â(ŒÙ–)ÖúàdÖ¥¤ruÖQ[,‚Í°ßt@Ôæ™#kðïR…€q‡ƒs;SY 
- ý½­!¯‰zÍð³2‘È2‚(QJp’ƒFZ‹'í±‡)¬³Ä!s¿ö.·®Óe“°k™æ lMôyò0mâchõüö1Ó…óÇgº½>€UæJz¹ŸÂÁ°ýOb]¥RlqÕ”é*´À=UëLÀ¸VöÊÉa'Õ%ƒœü ï‡×,ä‹,Øãüy#θ¯MÚÈd-P¦1PODºøꪭŽ¢ –¬ÚêÙàZ§íÍÑ9÷
-›Ó£x„Ö¢>‘[ „ûOç·ÖÝyÔÓîñüm<ù½–áãÝ{u;“öýM®0Zz`¦®à$ ok"\0u²PôÐÖB h³+Y]’XÎUºà–b>L,†M­¿Û¾;ÈrÑfËåïWúä&˜Ikˆuî«F(ü8+gÝÆ„·}ºàŽm
-endobj
-1121 0 obj
-1599
-endobj
-1122 0 obj<</Type/Page/Parent 794 0 R/Contents 1123 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F2 5 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 328 0 R>>endobj
-1123 0 obj<</Length 1124 0 R/Filter/FlateDecode>>stream
-x­VaoÛ6ýî_qÈ'phËI'H3¤­³¦ÈÒ, ë0Ðe±£DU¤âùË~ûÞQrb;ë·!ˆ![äÝ»wïù½ÑŽéhBIÑ{÷†×gSœáÍdŠ‡”Fb4Qœô£S‰#AWµ"Ÿ+|ÊrM–I;×(G«\•ôy>Ó×>¿|RµÓ¶üú†°‚§R’Žä›ø[oD‡ÑDL‘¡Ÿ­Jÿÿ:¼>¦(jóŽOùí#Ç\Û†RK’îf1}¹™=’­9¡ƒkmLJ÷µ.=Ñû”³M(zWÛ•SõÁ€JKsY,$á+ƒ#—Û5•à䳸ÇņŠ)⧇Ÿ{ÑÉ‘8¥Éx"FT€¨10·ß Í™2€¾ç(6‘%ÑBQ¦ÿFÕ‹5°WÒ'9eµ-(0°›«^RŸrï«óá0‘µ5b¥K'š')J3üÇ(Õ¬†ŽÁSä¾0»QvŽ"ˆbÐÒ¦[ic‡.Ó¤* {Àý‘3»º0#=zØ5‹lÖr$èÆ“4ÎR(}£Ä6¨ÆŠ¶íUmFn@®AièmU+¦V—K2ØjT)‹N{Ùíâ›J<"CLi-—KPøá¶>Úú¯ÊHôož+AÞ†vo7P&ÛÆÑÉô Í9žž¢Ucü#h¶/ê““ÉkQ ú@`7´TE@F`$­5HÁï«ÒX™Ò
-ˆ¸2Ê ¾ óVºîGÚ½ÖµóJj†ÁŸË¹ÒDƒB¿¸¹‹?<|ùeIÏá &=ÄòT‚X4ò½­Ö¬þ._‡ˆIu­ ±æÎ"xˆ±G/³(fW†&8*çÉùNNU²,ôÎ¥”
-Șé¹l­—º”rÀÛXƒ`·ÒzH
-ôAæÌΫîgA„¶4ëŽÙuà&f«˜å·jt½a½HUž•ñì^^ßÚc5Ÿdâè{½»¡b¼-ÄÂþ-ÓSØæÃdâãé%<;™­!Ÿ¤6?·Êq
-úÜŸÁØiœ]!*š :D
-|ñâtQ%iÊc(d|éáó€d¶ñLe<ÅV¹ÆlFìçÐ{õÛª·˜Û¬GãN‹ÿ¬ÓÎDÑ—Ü$pQغ1̯~yw…CÙò”§6i
-ôÒãJÀpà]‡í¶ÿñ~A[7ŠãÉç7ãêG£3N‹Óâ×Þ¿DŠÂ¤endstream
-endobj
-1124 0 obj
-1118
-endobj
-1125 0 obj<</Type/Page/Parent 794 0 R/Contents 1126 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 335 0 R>>endobj
-1126 0 obj<</Length 1127 0 R/Filter/FlateDecode>>stream
-xWQoÛ6~ϯ8ä¥)ÐÈ–ì8Nž¶uK[ h·Æm0 /4EÙ¬%Q#)kþ÷ûŽ”ÅéÐ"H,Y'ÞÝwßwwùç,¥)~RºÎh¶ Yý¶:›ÜÝP6¥U'‹ë%­rš&Ó)¾‘¯·¢ñÊRºLèíLJÕGúUJåÝ‹j-È™ÖJEÒäêåêÛÙ”.³9Þ¿ØkA¯¿Üów|zŠ/ùôËYšdüÇ¥ ½«½5y+½6u4Sšö¦Ù5F7ÚQ®öª4ÊI×$jÂeMªÞkkêJÕ>!ú½7±ŽZ§Ø?}½xmjÙZ ú¢¬ƒ']oèþ༪¾¾$oú¸ÓYŒì\n•ÜéúïŠÒÚÕ¦ƒGGt.MUiŽ×jÕs‡óè G{aµi]𾶢ÆqŽ$^+:¤
-ÑsÖ:ºg“»g|[óJÈ­®Õ£-Ù¶fšv]jYúBêuY†xã´7ö@…±ýcp+ 4ÒçÀR+B¾Ä@»FÈØ(÷ŠPrY¶9 ûŠ¬;ÔœÏé›öãºÝ$„@‚À¯ï B†*:qpìa¯§ëÀ) ¯djD¤]¨Ð£ï­q~D!šÏæ?F{:ýÚuuß:µþ¤ÿ6mÐEÅ3¤øýº Q!öøÔ^ÑÃí­é ÀÜ,Kܲ!£=:JšÚƒ¿ŒÇI¶ºÎõ^ç­(©€˜÷VÚ¨† uÐ>Î,Ù1«£É^s!‚ïPm¶Œ]†›€þéùÙQ¥yssnCP*Wâ\®üZùN¡Á‰úêÛ Nƒ
-·X$ š¥7ø[Q–rŸwG¡Ï²)Žò]’óúüé=Ýþ´nåF_®uÍÊí«û¤õŒu;›Þ$Ëè6»~TP-t;â<ýˆDÌ8™8£±æ˜I‚¨6¶BÍqÉRlj8´Ñ{°€)Tµr‹fM1}¬)É°jø:ø rCöÛïsgÌÊ0PLë©Û4Œ>4o¼Uï”jø˜ŠZ|ʸÎQÇOü†0ˆ@=׫
-œâ!²Àg¼;r+½á/ÇÜZ! ÎÒˆ<W")øàèGÅyEÑ3€Ønµý +»®Käõ” d8 PGÏÀÄ‹$äÉV»0{9½xk:F~£B„/ ÃzG°-P*]øŽáÔ'BNo>|¦7¾çMm¤ß‰¾¾Ä6ðÁ „~ûcn‡ýhhøý ÍVK Î}:2Ó*Tl¬A§âŠ=Z-e ¥ ñFª£Øº™*„&0·pÐIšÜ¢"_Þ#1°%¼êðÎà0#ˆhCðd+¬©¨ŸÚOqZ˜¶=ÔzèçZÜqŸáŠó:Ʊ†ûum^5 /Ýa\òH"õ¯¨xÕqçpû3²þ:–œ.MÒ4æx –cn%ýአìøÑc³×,Â~,’ [aƒk×hž u<-ž4P™ôÔOmªEL°R_ ¼Ãæ†ñ„âÁ”W©!Z
-{HB—¾Ä’Œíkt¼Çíq‘øÔÆ Ñ—ü©=Ú*3crwÕïÙüæ0;»Ì鶉ËÂ-î9®K·Üî­A«ÀœÓ¡Nî–ý)—œ÷ì­1ýü ¡Çõd/x5I¥S篳ÿ
-endobj
-1127 0 obj
-1482
-endobj
-1128 0 obj<</Type/Page/Parent 794 0 R/Contents 1129 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F1 4 0 R/F2 5 0 R/F4 7 0 R/F5 8 0 R/F8 10 0 R>>>>>>endobj
-1129 0 obj<</Length 1130 0 R/Filter/FlateDecode>>stream
-xTËnÛ0¼û+9))’ìÚ®Ou^È¥HÚÍ%@@S”¥T’²á¿ï’”Ûí¡0 HÔrvgvv?F bú%˜¥OÁ›Ñu6ººŸ Iöh:Ÿ!ËGq#ãÁK)ZTLÿÖØÉ…T`è˜Ö[©r˜]'p™½J2 |£ýÉ7ˆ\HŒ0FÂ~ö-L)ÀeÓ°6wŸC*‚ræÁ؇_ÝéÃá&#̱è´P¡ôþM³fÅ"©Ö‹+zUR†;=-$<*!++mU×àJ0#ˆU^)ÁT;pV×"÷„ÕVµU»v5£¦hm†ZöŠ["¹ÀkPE"rAwË[››&ã(µ´ [¯ ÓX)Öòòõ2‚«¼WJ´¦¦Ä’žt'Û\ÃH5Žbäb#jÙ5£%±àÇtn~=°BC’¶
-¶bÒb% W–¥_íÐë=¯Nºo\¨Nå
-`{“‹Â“g
-hYCé±D]‘²8cé©"õ¾€Bö„%}ÛqqûIè‚Ü´¦
- ÇÖu [±‚®ŒOdM"Û³<J|ô¶ ÔDÒÉÓ;iOJª+Q ¦}w¨f'6—}M2䲧r²®åÖŠ3øò܈ǂÿ¿C…çå÷ëå[ú–þË•G¦´ãFÊ(7j[f»-ÑEúT^ºÁ|Îo¼díšÚÝEÇý/(”lÈå¦ô×ÏDôbl¿8ÌáÞ³“sì(Ž¿FSkh«@ßåvvh"Ã' ~—hw`2žSÌd>£ç”þJ ð»f¾Ÿéé,²{ÈNüçºq:áIÉwDÜJÞ[Ë3Sùþ‡‰»úkÁMÉ:Cb%ó/Ù#–œ ­ñlŽGsS1ЈØ'Óy4ó›&I’¡è£?' ˆ©endstream
-endobj
-1130 0 obj
-662
-endobj
-1131 0 obj<</Type/Page/Parent 794 0 R/Contents 1132 0 R/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>>>>/Annots 338 0 R>>endobj
-1132 0 obj<</Length 1133 0 R/Filter/FlateDecode>>stream
-x}WaoÛ6ýž_q0,RÙ²“Ø)Plëºvöak ú…’(‹ %j$Çÿ~í:ÝÐF–-òx÷îÝ»Ó?9Íñ/§Õ‚–wT¶o6¿m.æÙzMÇ‹ßâËœÖ7٠ݬW¸].³;òšjÞ€g°r¸`õìÝ=-æ´©aünµ¦M%ÏñKyõk£ú¨=å÷}Ô½óÑt[z3lËÍ× Þ™ß¤/—y¶ÀÞ+,Í3úÐE瑱ŒÆuié åù¸t±â…›F“n•±¤ªÊë¨vžŠa _ù¤@&PPm¡~–kæü–MÍéåâÁÁÄŸV« )ª\`.šªÂØ_«©Ð°¬iï
-CÑšHê䜌~±Á]SŸŒ­ÉÔ„E
-T6ªÛêj<7_¦ wZw8Gö„kÂÒ¦VíqXÚÄ@±OÇ€ø—V³EZR‘‚cwásöý¸ü¢Ê±ñv(þäJÕñ§ÚÖm£mOÑ«ò‹wÝtjFŸ<F(wº¢bà+]™RÅgqm½zr5õÚÚ5Žº¨ADcp…¿×ŒµTW‘®n ý­H©Í#¨¦<µŒyÊoá†ÈˆFÄÎ8!‚3D{‚),œëÂN{à$ÖFÁšJá7fÛÀ °Ôì%Œ¥åâ‡B²Ÿ8u’g Ï8H—•~ÔÖõÚŸY{ƒEvy’"ö0’Õ 6‹½ˆ`BÌè,EouD
-aà$ò¶ñh„‘¦Ì#=|[º¶Ïzï¢+ Yh êô.Œx ´SÄÙƒ@j˜Ïürxôa u½.Ü(¼ ÂI…Õ-§^œ” ä@Á“®6ÛÁ+®ÌÃBøØq‚°Ü抇ã1”´¹38¤D.Îïä´T!í
-_®J`‡3Á //èvíq¼èj$À!¤àþÚÈçy|FðR©k¸üYç`Ï ÛF@g2vñ[\•/»k —$º"ó¯,!E "&¥tz
-{§ êÕVƒ`ЉûW³ÙA¤ÒÝL#ú<§›<‡'9^৊Ÿ*èrµu9ª/¤t‘Ñ{Ýi¯,™®–<ÌÞ=“Ò7Ià’¸‰DŸ
-*FCX2Æô‹ÒPkOÚ{çQ¼0x& ÜŠr&IvÅ£q(‡ÀpÌgˆH£¶V
-O¾á¨Q·­ Ý <¬vÐd0œUÃ@W‡Ø+ßròøþ[Y¹¹#”Î#“PË=4ìI˜PûÓÇ÷y~›­i9¿G·k)¿]eËñ›¥OÒúh™Ïñð´ÁýÎúw“? ôo$yh“rzåUeÔ¶sÁ$Ï¥¡òóŸˆ6ÜwðÿQû=™–[™êâ9ƒÇâ5]i‡JƒL>Š¤°GéÇ&!rl!ÌëŽ[L@!À¦:8”œËT6è'U2w¬HÔTŸe¬rœ…Do*-3ŸyÌUÔ]dýÔ?B‹,„‘ ždwsðöÿ¹½;ö7Ü^fôVsl–zœ(žq@ñ鼎²êö‰D­QbN5Yh4  ˜&Êp9s €Ö $Q
-¯ë!ð:X@[@®CŸÜ3¨øèc5°‹fBŸ¤ÓKŽ¡eõ`9X«N dX‰ ‰’s<MK)„|N¡q;lûÎÑ“…I{üÐ{ƒ„cj¡±!&Ã[–5鹕F¯·×€ŒÅoÏZ‹X]j¢• zU>:6¬ø‰Õ1-²›=›½»'¸+$ú:=™’vuPô;¦U™ù®/c-8[ŸÑçS%¯ ”LNˆr‚&øÈt&[À8b#,_Hˆëxè€Èã“iü u+¨/®˜Iš¦±dZ—¡f…L21âìW“÷÷<°æ˜7oÓ¼y8åóÉÌÞ<ŒòC7_Ól~f]©ìØ ¬)ð}›ýОmšêÿ?öL°Òÿ’½ºKÓ(Ó–JŒ0qYZÏìÝþï:t0>â•¢>ær'­ür|zÉšÆåÐ) < 1î§`Ʊx”QЄ*3‰_°#øô<ˆtû' ðm‹\¥év±¼ᇔµ<…&¿ì;Ó3ö¥29ój*OÑe”µn—Nƒ‹¤Ÿ0bª…
-ŠœT¦®¡qøt9xáê>DÝbj@ýÉ 7jéX²
-õ˜{É×õñ]/_ÂŽÿ“º¹[g+¼ñûS¾`#hq]ü înjÃendstream
-endobj
-1133 0 obj
-1667
-endobj
-1134 0 obj<</Type/Page/Parent 794 0 R/Contents 1135 0 R/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>>>>>>endobj
-1135 0 obj<</Length 1136 0 R/Filter/FlateDecode>>stream
-xW]oÛF|÷¯Øê¥23’?d¥@Ä 4iê¨øåH©‹È;õî(Yÿ¾³{¤e01RÞÇîÎÎÌžþ=™Ó æt}N *Ú“÷«“·w—4ŸÓªÂÊbyM«’fÙl6£U1mU±6Vg§«o'3:;_d—XŸ®ÖšøÓÛ;\&G§¡Í³ÂÙ*}nœ’¶ÑúÍWÃæÆÕÔènè÷ñ~(¬³‡Öuö&®)"Ú¯)uÞÕ¯Ü×*ÒZʵ¶D]Ð%K®)µï«™_dç\ÍNû`œ ä*ú¢Ú\‘²ØÌG­É먀AI•ó”«b³W¾ D…k·*šÜ4&øì
-œÍèµµ.D:n'·Õ^–ƒnÕ¬‹d52A`#ÇY›z­=jS–.2ú¤•G"¤%º™ÈQìè#__Ü„\ç³78q€¶^o•ïaWôÏíÃW¢FùZÓÎ5]«r&R©¢°oW' .]-/²%].¯ñïsüõšªÄów4}™çWW ÷ žÏße—ÝÛ¨½U iï©U•™þ,Žé}%pÔšsŸÜZÝ>|ºùƒnþ|˜P«CPÈ\C·¼d(| ±¨@3¡f"Z <OgõÓVÕr?U3‚k¿£ÈwÖqä™[ïr•kîEÝB!Ò,ªT×ð­@·‘–Ú3ƒ±3ÅWÜN0åð8í,ø*MÅ]«ÀãûÐ’/Á|Àî¡ÐuKÁU‘?=žöç
-Ñ”5À!纆 P±3QF“dÔ¨GÉ~ùøþù
-A
-WB·;v®—-gœŽIÂp…NÎôX³å¤FÍa8ÍÈ^™¼–úav~>ÿé0›/—ãav•ÑMW@±šQÃð`¢0{NàåïŸmó› v:
-X)8cT4àʽG‹è'H¡""ï:N{´¬kLd‡O>›‡î 5ŸÏ²ÅO^G× pnô<Z`þpPýuVH&×°ó¡G¶ËÈ…-Èèé‡f
-endobj
-1136 0 obj
-1642
-endobj
-1137 0 obj<</Type/Page/Parent 794 0 R/Contents 1138 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F6 9 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 341 0 R>>endobj
-1138 0 obj<</Length 1139 0 R/Filter/FlateDecode>>stream
-xU‘ÍnÂ0„ïyŠ9¦R1Ù9ám©z¨D‹_À² [5I·ïPSdÙòÏj¾™õwBÈxÊ Ó$s•Œˆ Öü"«Ê"Y–A™ôºh´·¨]‹ÆaïÃp'mÚúŒã—nñãâa<ΡCwpVàAí’•° d)EŽ¢*yŸóŒë+u
-bXOLEqÇ}óÖ6ÍŽ@—åó5¡|*$$e¢Bª¤ Û©Æê*.‡HD\ö?Ô2nÏxÞz<ßÆP×.>öÆ{ÔÀ‹¤˜k³ßÄÐy{15Tô;®/ªdÉn(«8µ²éjö>ŸaÃΙ–‰¦kœouËýº(®å£2çvÛô/v!+QòðQqkÄGò ²ùq¢endstream
-endobj
-1139 0 obj
-290
-endobj
-1140 0 obj<</Type/Page/Parent 794 0 R/Contents 1141 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 388 0 R>>endobj
-1141 0 obj<</Length 1142 0 R/Filter/FlateDecode>>stream
-xÕœ[sÇ…ßõ+ö-JUa»¸ä%¥K«JǤKy…Hˆ„M
- tD ~\ 26ËmÏ xôÐ0·Ë«•† ¦=¥; ë ýyÚ;–^˜c‰;5Üä¨Vš!(©;™>5=ë“;„Ҍڞ Æ,êÜÉôÒfhF2žÝ­o.×Û«¾)I‰¦l§˜“ÑÄ.E*0æé´Ža"ãÙz»Ü¯“GÀÛÓ˜ìÞÆ Ô!½ ¨¥·y˜0}j;Ö'(¥?!5³ 4ÁL_ç2È0 ! À9E¡Ñ€+aÔ‚ƺ¬c:WpŒ„-ëÍín\niÀ´âT]| À«iÁ9 bËàQOQû“WæNΛºÅaѼ)] ÞÔ-$fzoj½7e½¶¼Ó«7•„›2A›ÞŒë0ñÞ”õu3FTp
-xħõñ:#XDÛÆZ 
-q·]ÿœãK¤³LâSä¾
-7kÇ©‡Š[6u3½ð>;–úeŸÕ òY¬+}-q¼ÖôÉÇXŸ¼¶ ”~k„äfL0f¬Ã<x®éÍË`È(}7#’1"S#ãÿzoFÍåT¯s(£G”›“LüW÷ÙÄ
-DÈ2»kÄusƒF‹·gË–ÒMdüaH.!ï>¼»(¤­,’Áe½]ü<`H¸©&MñD™|æÍya!0S9ItÏ” DLõn½m~8¤g¡ÓJ¶ Ð
-ѹõ» /?ä]
-Ó…™Øý8¿ÆÎË0™"(Xæ„jdpļØmÿÒ?
-ë@AÕ#ÅÀ‘òn·ÿéŸ:8È.Øåp1u<Éi•åL <ã*]/ÌdvÅ;8rÇIäà ƒ
-ϯG?Ž1]€/ÖË«íîà6Âä,*WE¶aC]2:¢¾Ûïÿ²Ñ#çV²gN”¿Ìê-Šê˺+YT/ȢȈë.X”¶Ô¢†XÌÑ[FˆA ÄÙÅî¶ßJ& š«d– v?Vãå 5"Êß?ŸêÒ¶C.SoX½ Ãv÷˜u8¿Ma€ºž`JÖ2AìϯwÞIIË"€Ôž‘±¾"<% Ø +à pòãîbw“ YHSº‡É<æÕêãêÆ&¤ÓÓvߌº^ÎýC/¨q§¨èÃÑijHCÈlÏÎ iÈ‚ñÝ~½u+ÒISÖ2Œ1%ƒceÜÜŽd€L%Æ{ˆˆÞ¼üoß–$—µ‚‡XRØXDèñîaŒÃ“42Ç”}#O°‘ð\9ùYXŒfÇ8L.1ß=·Ä‰Á)†Â©ýpè 3!ºzA¾ØH^1ú ç§É Q#å3fˆ/ŒW»‹Ÿ0ôI-4+ëKY÷†poœº¦©^qÐ\÷L †SºdCÔø^É 1NÁx½¼½åyɤ‹ÉòÉA27Öålm—›”yÔÎ!ûbfÎ&•üÛ ¶ïûüÛtaålÛÉÜ{Ý}Ù¶™¤Ù±Ž¤Ù¶1Ì/H
-Á6¦ÇB ½‡õÉ4A’pÔ(Í×å1d0o ]‘É ÿD/È@Èðñe1ÐнôÐ6‰ôLAŠ v;28O á5‹°á!ûŽ`·#As Q‘“F'²àoýè­‹=u]–©uõ‚¬+/¯Ð›#bÛ¡k&ã™>Ùõév ”–5}²,ë1è5÷ã+µëÜ ˜PÊଠd×qL½Ë›DÙk™`·#£´­Õ!Ù– ɶE-&:¯ý:½ÖYWNû¬Ÿt1X·A2BPúЇM5_&¨%ÁnGFaÝLPë:‚1#Awq¿Rß]°ï6³”iŸ,¡d]¬&Ë!‰–UH2!Y‚ ‰Y0JëZ’u™˜Aw)þÖÕI­E†F/ȺӘ—,‘Öej]#$K0!Y·`”Ö5B².Œk¡ë ?…uqÌÕgr¤5®ÈºHÔˆãÙ7“ŒgúdÖÛmO(-kúdYÖÑëu,þ*íZ]H@ö`?œ5zAfE:I\áà ;\#$30!¶`”¦5B2-³ èñg0.²†ÑL/ȸ8b-G³áà?YÏÉL°Û‘Q×ɸL0f$èˆñu×½èÓ`ã¿?"Kd\=1‰![¨yWT÷Á2"ÙFy†À6˜$ú>Ͷ%‰lØÈË®v?"Rç“Eó)w7~kÑ ÷joÙqJQL6Ò ²,žõž…­ÌdÝÑ"™bÙQZÖôfY2Ö"=ÂWnY9‹–ALWðéb°l=±v˜Ú’
-}OøC¶©]^'’LûE þ<8 NFýP¼f˜ès›¼FâF]±>Ý„Þiz“ Ùñ3_ÈTØÛïNëúMv¾ôçÁ.H¿Ž#~Óuúä&¯‘úß8}º j—íဩÁÅuo›ÙÂ4µK‡;úwÃôçÁ$XŒùèÀç
-:€™XG"§›Q^ n&—HEì'`Ôk¿ #[¯D/Fš4>ÕD€%ùÒ?Äð  F2%>3ÂêÄ‹ú»ÃŠ^—îE à3 ø 3dªHCë ÃHTË ®c¤Û‘1L I½fÆ°ÞnG}˜?“©ï’gç*a·#Ä&Ï–ÄÔ~†.ï}nÔ~úóà›] b<1Õîhb|;ï´ ÈÄ馗ŸßÆÊ£E±_&o-ât׋߬ŽÏ^¾¥M/ï…âåT"€‰·áݸÍý‚PãÏá•V'ž×?_^\¯dÕ€³“—:§5éº3†~HÖŸ‡Ó7¹ý€,COžaj³˜\­Ìòt3&®ÄV3µ¼á‰ì{©I'âÅßõúÛ·gçC» 2i7ùZ3Œë ßîÓcçîKÐ×î ëð~øן‡Vhb‚ŒÄô0ü›\6Âj¼Ýw‚à­8ˆ`ED³¹#3V‚¬xr¦É‚û±Ö-ÿás˜ú“~‹yý&ÒÆñ 5lÊÄáñ™|@±BŠöxù±z±»¸Ûà½?ý ®èñ.PWý}¦I×ò+,ÆÿóèWé"bgendstream
-endobj
-1142 0 obj
-4385
-endobj
-1143 0 obj<</Type/Page/Parent 794 0 R/Contents 1144 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 432 0 R>>endobj
-1144 0 obj<</Length 1145 0 R/Filter/FlateDecode>>stream
-xÍœ[sÇ…ßõ+ö!ÊC`ì —§”,Y±ª"•ÑQªRy€@„Mp
-Á)!tÄxý¬Ø”D»ªnùRBè}_ ²jƒoýìZ/Uá3XµïÅeÂYµiqÓºiqR’ìªùRlÊz½í ?ï’›’FLÚJwd‚Þ÷„7ûáÝa{s™0¬g&M`8©€]ÜݬÛáæI¤iÑûgJpOZÝœg©v5sÿT ëWÅ0¬£^øz¤žqR5XD_ûj¤q¾¹½~˃A˜ã6Jd9C UWc!0ËŨ6Jö2,«vUÛ·“¹«Šb=£Â#mnι>¬k9÷N<ËûKwU×t2&°}Rºcf(ýˆ‚ÀzÆ«ÕîÍJ,ÜÌÑyMhq|*½3uòpA¼žâ¦íä%pÆ^¬úy;YV3ÖÇÛ#Âó<‘=
-žŒ¾É€xx½½9G/OnÈB`ú™´c´ÀˆsجïöÛcög–´¬ÅŸ (²G áÖF
-RJJô4œX`Äa‡&mí«Øƒ#©ÀèZ_ÅŽ)Hr„a~¥Žëáæb{y·ß¤Vb-züÕW ŒHUðä„a!0mHÓ¸BZ`„¹ö™A*0So[ÅŽ‡Ífw½9dÏc©tð0î›ÊDö´Eúx¹_‰×HízŒ¤¦‹æ䪙ò€Ü/ghCÍ(ãEé«="U3ꫵMsaŒ²2„æŒ?r’ÝcÚ œ‚Þ÷µ(ý5 t3ÞP
-Xýn³{³Éq‹eâr7C*`!˜¯j+°€elk¡L X% \¬î0X€°€çyÄg‰¸¼L °
-:š³&
-
-9üŠAZ`D²=Œt  {ô”X`D¡ L" f2 ÛŠÄcDqqÁ·Z™IXD,0FœÊ
-²°0z›ê¤ž¶-y‰€Àò©«O¢zÄa÷f²F†(vÅ
-xÈ«ßÇÍ.cH Öœ‰ÙcŽûM© É
-ŠqÑžÝ ¹»‹ÛoRøTÿ5‡÷Å&g¥v†â0[îÂ…>öž»Vv58ÀˆuŠ}H„Íü¥˜‡ zÛ3^ ÇM˜4a%kñ-Y&Z¬I{ó!×’³êÜ© Ù‰(‡ÔŸít2++†MfÅ@<‚Ð$5bÕ££Î1™“Š%?Œ·¥óp%~zñìß)FAíŠHýï/7ûÝö ÓÜb-HXC°aR*àQßoeý™d€`£cžhἘT1;«
-x–Ùég(8+â*ðì%×e\“±ÖÕD±žQ:#‹Äû%VäQVÈI VS:GÒžt¾]]—¡'!úˆ)„ë<xÖœ¿´á"u`xÞÂNæ°è:ŒªÃI#£ŽÑéýÙ¥¨ØU˜RÂ~üå
-´__öÜI;œ›åzßÊߢ³&n”4 #D÷fB*`”V³ˆ°–oJµï
-XÆájµßHöÚÈñªO Þ—€–¿;‡ŸËÂC-Â9<Ögl*Š5çòª±œõÑåG„“c„Bd Á‡)Êõõ0žG*´8’X› ë!û›Íþpµ §TC\ù£l^¬ú“k“^v¡R›„ j<Ÿuìeº6Q}´ëc›Œ'ÛD!j<¦(××ãD›$Fòf$¬‡”375‰$ ÈfAkZÀ#ηûÍú8ìóÒ:k¥KËÎŒ%)Ü“hÜÖIå}LZs€§ÅQ™ …y]¼ gÀ¢Ÿ~ˆ3”4ŽD˜+ÊCÐÛžÁ«%$B#`Ž.ÔH+¡÷=¢LaÂŒùûG ɧûÈgÿÕÙ5 GÉ®á‚ìŠ=XŸó‚x4œê©LìZFè}y2òL’Š‹™ (±=ilß/z
-çclíÌZÇ7b¤ dVyU‚ÞR€7¹È¥êË„â,@x>œo/~ã<Ÿ„0(6bௌQ²ã˜ÐE"qy9ce±€CPà"
-_¨å¤­Š²=È楤“¼4LùØSÖûÍêXfŒ$&¤Z¦2‰ì1»Õá—d\–a¦‡>%¶¤7`R©nWûÕnƒ&C‹ŒæŸ“·Yïm°3’s¯xQ¼·Yú3óX¦²,é£@ðÞ1â½Þ›QÁ *Ñ}uÆÞ›!ÁÑ,Þ;®ÎÈ{3!x˜%(ÔWã´÷&Pt2 R¶ðÞLAmQi.m¡öŽî ÉÄwe©ÂB´€‡¬Žzz¤8pÑÂ1ƒÆ«€¦:
-÷$ظ½Å˜RÊéçÏôÚVHñ¥B¬$ÅóÞau;^¨uøÜQNvðP|jí<±ÂÚ¹a)Ý ¦¾ ‹ãIwÙ`äP1­‹½þåÇÜi4'!¢gØ`2½ï1¯îno‡}Ù$¡„qÙd3ñO¡m’H—u? ÐaÜ—uð<„:OQ°§`1fòkXu¡Ï u3¦›#= ^ÊËbñ"{­)㸸Éï°îᢣrâ‘?ŠÑÑ÷ÃyÜ× Ào>/Ø„> hk„—DrâÓ„ 5’ø¶lâƒfvÆQ}Î@4ÎaNrˆ}ÂaÑ{òß³3vtd\ 3#ÙÞÉQ[Œƒ7Î욆§ø‰ÐÿpT =‡zßCKÖBá„•OdEÁpRúÏ­¦?ýWLŒÕ寶«5g,€å%‚xAŽ‡É÷J‰(i‹¶SBxsÑô¶g¼ÚÙ²¤ÃÊlÕPô¾§<ÙoñIÞa!0ìéL*à9|<”T`„WÓ-C xÆ¿b'Ž…¤×ÈO;W-àAaÓäkÜBnî€m:Å:ÝÉo|5ႼaêO}JO+kº±¹•P£0z#ô¾‡ø—„h,r !“ÈžSVáI=ª÷„õ„ëÕþ2OTÄ_’”°s`ë¡<åæμECBñ)™Q[Œð~¦ˆàMµœ¶¥zDˆ<É›îe§5zdÏSFþÐðñ¢xº—ïÑKldIú°ÛlôJ´„GççÔI»‡)¢Aè}‹xAÛZ$
-‹*Ø"ù:ÇçÚt, e5òÙ¼/¨IÃj9Ïaç4…Œ9éѹ`
-ýšqsº4¾V}Ø¢ª­éûHëã Öxøûõ¾­AêÙø¤¥—þb( l1æ-ÖO=9î+Ÿð×8‰^Ò‹pA­éŠÍy¤{ùTX ÑzLˆí1bŒZDҙѥ™ L_ 9— í›>¤–¾%[¤†•ðöøz‹—C&'ÛO_2“ûðÖiÍYW,
-É’~Å
-endobj
-1145 0 obj
-4944
-endobj
-1146 0 obj<</Type/Page/Parent 794 0 R/Contents 1147 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 477 0 R>>endobj
-1147 0 obj<</Length 1148 0 R/Filter/FlateDecode>>stream
-xÍœmEÇßçSŒx•“Çóhû¤Ó)‘Kqo¯³kðC°½ |ûûWwu÷¿j"Ž l6 g§ë瞪êªê‡ñ¯÷êjŠëjÖTíP­v÷¾º¸÷àñ¢j¦ÕÅëªî“ºf]uqYM'Ó)þºº±|µ]W‡×Õ£Ãþ¼ÞŸO»øùÞ7÷¤AhUÕòéÅ·÷Úa2­†nÿŸ4z±­^Ê9ãUõàqWÕµ|5z3ôø:úÞù¤›Tú]ÛUó…'ÇÛNþåú|Þ쯂¤vU=m& Û»xß1nÞ$q–€|WOfV^8À›ãf^- †¦“Îab‡Yî/sGH„yëD¡Ž:’$µ«šºÏvSS)Ö1NëãÛõ1Ø¿âkÅ^÷'·úOתDßjûÉ<ûV¸Ð‹ÿ ÉÜyPï<Hågí¤E{©|ô á»Ã«¤3’ÙU‹aÒ[€Þö]8aÀü=!H
-–«§âÆÜ ½ïûC° -†ˆ%¤q¸9¿¹9‹*›zþ ÷G^áŒÚ4“!5\Q›7mXœQU>Z€å£QG„‘QÕÏ
-®—oÎëcR‰#I­ÁÊÒÛBæ)"Höj=#¯D/ÿr½º9nο§^ IBŸÁè}ٮ߮·¡ÊB¼ÿ<l4™tù¾kKÙLTÒ÷]çÂ=&n (©Ft…‡+EÅA0B<ÙŸ‡Ë›ÕysØKŸ`Œ;
-ƒ¢Jä út¨X{$}y1³qêQùy OèY>jgDxz8梂„bÀ0`„Þ÷Xvo¶ësÆHxI’à̤ö5œÔÀƒ.קUa¨4$X¬¹T°–¥xÏÂüS…0yA–G@àÇJ <âä†'‹Ô˔΀Ð
-²:æ-OJ;Î$–ì0Qw %×v¨ˆm5 ',É–dà„áI ·=¨‹¤`¸ºÁ¨4ÐûžÁK{$‚¼˜»‘¨žñÓfyxwÊæ'Iñ!Il–ÓË<¥‘ßœd‹lßÔˆŽ¡T‰Þ×ç·–¹ÞZ˜„á#õV4X¸ dÉ>ÐæôF2Xd–š§c€ÞöˆŸ®s½O2!’Áz ÐÛ°ÉvCJ"âA²Øc
-ôú
-ÉKF”øÁåB_›àÖÁRðyÜp=ÚÈ”Á¤”ÐÙëcœW&#ŒÒÛñðÕ +ú«°Çötn/VPòûÓ¢0ÈK¥.(K¢
-q•¦ÀN=
-¨±uaBÔψñY¯ÚXí´0z®!âEÑN»Ýgç<®†H€¹l@PÎñÓõ2o="]3‡«„Þ÷½Ð”†5 J
-ŸÁL“xÎóãáí 7aDÆwâÇÎ s)Œ0®%̶Ⴀ2eÔ+Å]‹ ô€*¤·„akK¸X¯ÖÙ,#‘…8Ó‡ÔÀB~<E"Å|&K¸}˜”áàFØJogò +ãétÖ¸ÒBFxÑ©<S„ªÖ
-Û†ÇÒ'Iäçpü%®¯K¶»—Àí ‚rJ¶Á£“‡ 22ªõ¯`ï抈Q¹e†¸ùˆñt³:N‡×Å×C8‚¢Q™ÃL"ûÞ¼Xï´`L‚À bv£ <Á{†7e›e¥^wHážôh¹Õ-”O2þœ)±rÒkˆ=á‚LÙÉÒ’K ¨gËè*R¨º¥þh!–!ž-wy¹žD |¬Ú`¬2`!×¾/q´g³Ê ³-$2†¤#–¡V×a„ý;[}ËUa‹9GHçA¯á‚¬ýŒÒ9žÖYCâþÐ3Ä#Æó-öYñ9í BŸáø•Á¤¾7oÎ×8B´Y-e»+gwÄaƽJßàqO±q¶Íɽ»}û8S`%²$òpA¦Cˆtþ/D8J:Á|
-À’9b=Ä€œ7„I
-³æ¸'õýÿÐÜõ‘ÿçtƒÈ©PÞ¹Ò»d¢LB\*l¸j žª€·…ðž<b¤©m¼²0Ü +QP3£Rß,+¥ÐÂR`„¢Ú2ë6Ò’œDI9ùm)ÚÀSl`aA`XD›¤›ÔÀc\`‘©Ó‡–?å1ƒ)ëŽNÅ #?%£.ê( Fe
-ãþ\’&‰„ù?|›+±=ˆ–X
- ¸ ±a(Ö3ÜùR–ŒiÓ©&5ðœGÛL>ÓX“´˜$ÁÁÁ)'5ðœR^±Ø!®í#¥#Dò,Nb9Õ¦ž«¤nrøÀÐ<˜WHêVOêɺn¼ qèf¢%ã†òu‘‚§b#'
-‹ÃVãI ¾”/—§Ó΀ýžÞÐ $
-9S6-¤j·˜²(†ÁÅ q™Ã¥ƒ¡q8þÂÔÀ÷…Ë5’£—µËОSQv]Ŧï
-~ýaü@%±
-Þå×0‚w¨,ÎYÉÏ
-€Ã®ã¤íâFÃK±Èòñ®ýv]ÕÈŠ/Bb7ÙCa‚2-âõ¡x^‘€8B Þ)§P wo>”šr†Å "Ô"¿=xúM˜ȯÝêoFÍÌv6Kr½>+c%c´x‰™t óR#ª| § @­7¤Õ9{0"êÄÁë£xoE:¥Q²ï‹±8Æ_88ý#Û¾HCó8í…·Áo{Ô3¼
-endobj
-1148 0 obj
-4511
-endobj
-1149 0 obj<</Type/Page/Parent 794 0 R/Contents 1150 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 522 0 R>>endobj
-1150 0 obj<</Length 1151 0 R/Filter/FlateDecode>>stream
-xÍœ[“·…ßõ+ø;Ysn$'/)]"GK«h•ÒcŠâÎJŒ–KšäJv~}N Ìéå²ÊÞ•­*gç#h4 |PM¦øWMæõ¤™MV›^?øîi?©§“×W“ªëϪÉlÞN^_N¦gÓ)þºúöõòíõ0Ù^MooŽÃÍñðç×ÿ}ð÷פ@(5©äÓ«ï4³³édÖöøÿf2›ž-ôâzr!_äûw““ª’¯Fmf¾Ž¾·ªÏú³‰~Ñ6“j1=ë,;Þw„'çÏ>{ñŸÇç/^¿:ÿáìøÓ1ᘠ¼ÙYcyZÀÿ:êGÅfR7ÕYíõ¡€Ó¿Yß\n?…u ´‹³¹¥hGyñ:H
-X½õäâï“ ¾³®òU‚h ÉÎ&G ,uƒ±qmR ÚŽ!I
-„P1ë'] 
-è±ÚÙ},PTâ úæp\×£©°=­düVĬ+¬UÒ<Á2@à[ Ñd}̘Ub³9˜Šh‚qiW+$Ãû¶QrYÅõ
-©h½óßËz Ïñ]7 41l7\ívs·~@pˆõÖ8 *ØnðxŒÛ-oÞÙ1†ƒ€ÆÏ€†T
- ¬Pa+\‡TÀ3^>yœìU2
-†ÃY_ÈX9ëëœõ)
-M¢¤ ~ Óô¶˜5×árÌB,$Ñ
-TSÉ
-XÀh¾¤€¾“Ô“ùþ„´úý°»^¯–´¾'¥XDì–£,‡gsÒÀzBæÏ´€%6owËÃáÓA’xMW“„¶œ«õõŒ°úâôî—â¢ÕNüDÛO1D4/Ôè8Üö2Ø{J'VÈÛVH—„Öɇ‘&dr{­™VFoûZ\·{äféܤƒ4Œ™jèý‚"iõoƸ„âC$“b0‰ì9ÿ> ûïž/Wï×79$`¹˜‚ŒSK<ìáj…DKöЬDÁ®ç´òèž²¾¹Úî7fÄZª>·Yò6ÓÅIRje–
-øÊŒñ‹€˜‰ã3­’
-xÄO¾Ìõ ™°¤£,d6?ñ OÖûa»ù9,ë9j^t¼Úiçó1Äy¬PF³EÖÙ»˜Ì²¥‡x"¡BÒÍ ô¶G £¼Û©NóËuþWð;•uÍ„í¬‹µá"YÖlÒÎ:Á Ð’PVQ#S ¦8½RBl‚ñLvç.oW’ &úc¥&­!Õ”S“m¸ ÖélŒˆ¶q©É¨@ÛÀÀºYÛÆ.nw»íþ8义…À ¯…QØTÀÖ„‹€@Ð#”jÃþã°êˆëf÷½\[_ÌÌxn$Ÿ¢‹†6\PW`°Ó³$‚Ü(V
-ûå2A™žUýÕúÝ-G[,†Å U‰IœQ©€gÙéÄ„k_!€õŒOëãûÔU,»k+¢T§&]ôåÇ)~ÃĹ˜TÉRY}m¸ ®„Õ‘D±ì‹*´ÚÉ ¬û$.²ŒóÝpcÜ9édä˦¯¡$°!Él"ø’`êó»ÉõüRkÛælà3Cì!qv¼›³é%VŒ Š>F•4§ìTš³dœ$÷”ؾ>adÜ»EÍ»X°‰6 ÉH©·‰Ô¦‹Â×Ìì$™ä1±eôÁ×4Ž ®s\Ž…ìV¦„Í C‘ì–‡ðI
-é ñ×V¯ìƒ|}îÝX ’ÁÅ 0…y…vѦH\ Ù,o–ï† Î†á!ËÓß:UþÁuÒÈ9ÊiÂu<cåÌ]* šJ¬h± ÆÅ°ÂLqÌ`X‰.@z]À5I|e¸I’ª®. ëYÝÓ|<»÷åÓ"½ çb˜Rž¼ãõòìÖ„0y/\(
-Ñši$Ǿ3„d‘¨ÆBbfb5{Wî× 65r^A¶@fiÖ“yÇ‹hfŒR£U@/Ç @o{ÄÅp<RhI:t>ö'1Wq5ô¾§Ð!2Ò€€~¯,!A=b\Á‘ô ë žðæÙ‹‹Ôá,+–Ãp¢\Áñ„w!À•Ö¿«n7S­¹èÍö¦¼j7Rá‚<’ìfÚ\8–nÞU@ì8Dƒ(' B!ÚwLQ®¯Ha‰Ðµâ$™ QLU$E—b}‚@Ì€0IÅ#ù¼=@IÄ&‚g3
-o¼å 5^ŒVT-Š¨È%»“¯¾Ì±
-Ã1û$ÒJ?Š[·$-àIËËKd4CÌÝËË‘÷£"»"~¿¢6@«Vц¾ Ô—á]7¤/éôì(B#"Á
-gš (±-i}8ÜÆž­ï9ÓWMÓîU#Ø)ʇ6dog‘Âó+R¿Z/ àÜ1DRTÜ'0,½ïØáÛ-÷ëÃö&8
-¼BûÇØäsm„ð?ç;ÂçÑ‹àE—í€Û°Í¢jLáí„Õ¡M
-ýùîz»úó²±x/~Ó÷Ï\»f ›ˆ™$£>Ͳð'ø`-5ÛKÖ`Ì„sƒ @²
-endobj
-1151 0 obj
-4777
-endobj
-1152 0 obj<</Type/Page/Parent 794 0 R/Contents 1153 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 555 0 R>>endobj
-1153 0 obj<</Length 1154 0 R/Filter/FlateDecode>>stream
-xÍ›ßo7ÇßýWì£Ü)û[Ú§ÂI/m€icãò’E^ÛêYZßJ²Óÿþ¾3r‡C¨qE¬(Â,çãÙ/‡Ã!—þïY‘åøSdó2«Úlµ9{suöú]—•yvu“M7+²v^gW×Y>Ësüëêüjùõ¾Ï†›ìí°Ý÷ÛýîÕÕïgÿº:£Ü++èoŸ~:«ÚYžµu‡ÿo²6Ÿ-¤qŸ]Ò2ãmöú]ýhxÓ6øqêçí¬™eòÃm“-ªÙ<F»ÇðaùÍ›+‹MVä•uÍ=7öß6ë=ýøb1« ÚÕõùìþƒû"ŠÓ»jð6^onˆÞ¤)º,¬ª­QU
-D\d/c§~yíí•IU; ÏcÀ¸|¢À(šYw2áj%m;·ø°>ÜP’Îi¢™<PFT!t5ƦÑ'jÂø<®÷!\•%ØI:btuÖ$¯+ù|"iÀÊÚ´nÙbY¹¡dmæé²U”FV!¸ÀÒ'kÂH£UÖL¨uãaì¯×«ýzØRØÖ—•×ªÊ.!³ò qC©Z×é¢UTFU!y‹9Ùh„@-äC¿Æ?|Ðvˆ×ºÁŒ(¾ƒÅl–¾äj_V×"o¢åª¢ŒïE况¢¥Úf€Úˆ*Ušà4M—÷ÓWTAPÔg‹¬ÑynÝx{¿ö;™²ÃlzÙ8å]…ÕÕâ´XqCéZ¤yUí•8¾ÅÞ  íª†j*ö¤)¦¿2võÙzëŠÖ”w}>P¹¡Íë#K•Ú(±¤BèhAn4ÁIš0\”…PÌ(Ty½ÓÁZGö‡­Ìü’ª±—T¨u—Ok•kLºÖ+6¨=éê ‹kD`]SƇP• ­ÿ-Î"€<§‚M;ñ©ßîÝA²Ks¢rµÚJbÅAIV·5çÕº@°¹†Èúú]#‡&Ô«1 öíÝòaß>è”ù5+–Žˆ%-³Ý” ^
-!öLœ‘Çðñ²ô
-‹‘uH:XT”í´(8¢ø¤ø÷!/`KÁò\Ñf€4tFC„›B‚¾Ú
- TÀf||ËP)B)3zé`å,|RÔV`ð׳˜!XˈR}ssVHU§»ÈÁZF”ªŽ_ØD…"†¿×pÊá†5„Šòøä™Ë)uö5Ya° œ¬”¨ÄÅT€( ª…è>²—çÖ‰ý]?1´ ص‘ßôRòèpÄ‹å6lµ 8
-^´”°¢÷ð,ãa\ãšÍ”p”%8|Øs¤ƒå\kL° Š2¤|Aác¤C‚ž¶÷Ãô%S›„r¼ˆA¾ƒ= #ÝñiKÊ´‹ò,'Së§6Ã$)ècd ®…è,¨Íh®RMA| q3mçv 4 íâSŽ¨5Í::ð«æT… 
- ¬ç¯úÀ¯šÓšÞT;ðó,>‹XB·\qò£loyCãË®‰7òÜø Í3´ g ñ,åbµêw!›kC`æt"ù‚ø áâ(¸¢¬gùœâ,rE:XÊn8Œ«ð¡YÒüáé¬1¾ƒÅ¬p—Çû¢Í
- Ì7Ä…öÃw° „ÖSÿ•OÎh#ò½ÇÂÍB;"€¿²°¶ÜP#Bžõ]c5Á&èà”ÕC8:â‚Ȧ 5t,<£±ˆh`ˆ aõÈŸxPŸ¾xޛƃʛg¹´,pâaY˜¾g–¨îãUáXyãYÐZÀº…@*Ÿú” -…xä<·„OýÃ0îUýªMÂ,ñï(®ø–ôæpë¾Âå(Á_f¦L«>›êµ»œ«k½®I­Ýå"¹à‹X óúãQníŽXîyÂ8éµ;–‰ï%ÈÚMŸŠJ
-…µ»líåXDŸJ-´Þ;úÓoD
-ÖÉÊâÛr¶Æ8p‚éÇq¶ã´Ås”,K¹¤Ë¡Ç ¥,>;Æ ²€º¢7Ù@>*5ÁI›0.öûåê.Z…è3Œ3ua[JK\ñlëªÁëވƇ~ÿ'ò…&u°ˆ°%Õ6 à;%ÔÆÖî¶ù¬¦-ÁÁ}8Ë´å<ŒpýY~ÇUÕª®ðK1%7T@öN/B]0ä€
-endobj
-1154 0 obj
-3118
-endobj
-1155 0 obj<</Count 21/First 1156 0 R/Last 1365 0 R>>endobj
-1156 0 obj<</Parent 1155 0 R/Title(Table of Contents)/Dest[1140 0 R/XYZ null 756 null]/Next 1157 0 R>>endobj
-1157 0 obj<</Parent 1155 0 R/Count -18/First 1158 0 R/Last 1175 0 R/Title(Chapter 1. How to Install and Test SAMBA)/Dest[798 0 R/XYZ null 750 null]/Prev 1156 0 R/Next 1176 0 R>>endobj
-1158 0 obj<</Parent 1157 0 R/Title(1.1. Step 0: Read the man pages)/Dest[798 0 R/XYZ null 726 null]/Next 1159 0 R>>endobj
-1159 0 obj<</Parent 1157 0 R/Title(1.2. Step 1: Building the Binaries)/Dest[798 0 R/XYZ null 589 null]/Prev 1158 0 R/Next 1160 0 R>>endobj
-1160 0 obj<</Parent 1157 0 R/Title(1.3. Step 2: The all important step)/Dest[798 0 R/XYZ null 174 null]/Prev 1159 0 R/Next 1161 0 R>>endobj
-1161 0 obj<</Parent 1157 0 R/Title(1.4. Step 3: Create the smb configuration file.)/Dest[801 0 R/XYZ null 735 null]/Prev 1160 0 R/Next 1162 0 R>>endobj
-1162 0 obj<</Parent 1157 0 R/Title(1.5. Step 4: Test your config file with testparm)/Dest[801 0 R/XYZ null 375 null]/Prev 1161 0 R/Next 1163 0 R>>endobj
-1163 0 obj<</Parent 1157 0 R/Title(1.6. Step 5: Starting the smbd and nmbd)/Dest[801 0 R/XYZ null 264 null]/Prev 1162 0 R/Next 1164 0 R>>endobj
-1164 0 obj<</Parent 1157 0 R/Title(1.6.1. Step 5a: Starting from inetd.conf)/Dest[804 0 R/XYZ null 750 null]/Prev 1163 0 R/Next 1165 0 R>>endobj
-1165 0 obj<</Parent 1157 0 R/Title(1.6.2. Step 5b. Alternative: starting it as a daemon)/Dest[804 0 R/XYZ null 262 null]/Prev 1164 0 R/Next 1166 0 R>>endobj
-1166 0 obj<</Parent 1157 0 R/Title(1.7. Step 6: Try listing the shares available on your server)/Dest[807 0 R/XYZ null 682 null]/Prev 1165 0 R/Next 1167 0 R>>endobj
-1167 0 obj<</Parent 1157 0 R/Title(1.8. Step 7: Try connecting with the unix client)/Dest[807 0 R/XYZ null 505 null]/Prev 1166 0 R/Next 1168 0 R>>endobj
-1168 0 obj<</Parent 1157 0 R/Title(1.9. Step 8: Try connecting from a DOS, WfWg, Win9x, WinNT, Win2k, OS/2, etc... client)/Dest[807 0 R/XYZ null 328 null]/Prev 1167 0 R/Next 1169 0 R>>endobj
-1169 0 obj<</Parent 1157 0 R/Title(1.10. What If Things Don't Work?)/Dest[810 0 R/XYZ null 750 null]/Prev 1168 0 R/Next 1170 0 R>>endobj
-1170 0 obj<</Parent 1157 0 R/Title(1.10.1. Diagnosing Problems)/Dest[810 0 R/XYZ null 573 null]/Prev 1169 0 R/Next 1171 0 R>>endobj
-1171 0 obj<</Parent 1157 0 R/Title(1.10.2. Scope IDs)/Dest[810 0 R/XYZ null 501 null]/Prev 1170 0 R/Next 1172 0 R>>endobj
-1172 0 obj<</Parent 1157 0 R/Title(1.10.3. Choosing the Protocol Level)/Dest[810 0 R/XYZ null 403 null]/Prev 1171 0 R/Next 1173 0 R>>endobj
-1173 0 obj<</Parent 1157 0 R/Title(1.10.4. Printing from UNIX to a Client PC)/Dest[813 0 R/XYZ null 750 null]/Prev 1172 0 R/Next 1174 0 R>>endobj
-1174 0 obj<</Parent 1157 0 R/Title(1.10.5. Locking)/Dest[813 0 R/XYZ null 639 null]/Prev 1173 0 R/Next 1175 0 R>>endobj
-1175 0 obj<</Parent 1157 0 R/Title(1.10.6. Mapping Usernames)/Dest[813 0 R/XYZ null 171 null]/Prev 1174 0 R>>endobj
-1176 0 obj<</Parent 1155 0 R/Count -15/First 1177 0 R/Last 1191 0 R/Title(Chapter 2. Diagnosing your samba server)/Dest[816 0 R/XYZ null 750 null]/Prev 1157 0 R/Next 1192 0 R>>endobj
-1177 0 obj<</Parent 1176 0 R/Title(2.1. Introduction)/Dest[816 0 R/XYZ null 726 null]/Next 1178 0 R>>endobj
-1178 0 obj<</Parent 1176 0 R/Title(2.2. Assumptions)/Dest[816 0 R/XYZ null 549 null]/Prev 1177 0 R/Next 1179 0 R>>endobj
-1179 0 obj<</Parent 1176 0 R/Title(2.3. Tests)/Dest[816 0 R/XYZ null 182 null]/Prev 1178 0 R/Next 1180 0 R>>endobj
-1180 0 obj<</Parent 1176 0 R/Title(2.3.1. Test 1)/Dest[816 0 R/XYZ null 152 null]/Prev 1179 0 R/Next 1181 0 R>>endobj
-1181 0 obj<</Parent 1176 0 R/Title(2.3.2. Test 2)/Dest[819 0 R/XYZ null 722 null]/Prev 1180 0 R/Next 1182 0 R>>endobj
-1182 0 obj<</Parent 1176 0 R/Title(2.3.3. Test 3)/Dest[819 0 R/XYZ null 505 null]/Prev 1181 0 R/Next 1183 0 R>>endobj
-1183 0 obj<</Parent 1176 0 R/Title(2.3.4. Test 4)/Dest[822 0 R/XYZ null 577 null]/Prev 1182 0 R/Next 1184 0 R>>endobj
-1184 0 obj<</Parent 1176 0 R/Title(2.3.5. Test 5)/Dest[822 0 R/XYZ null 413 null]/Prev 1183 0 R/Next 1185 0 R>>endobj
-1185 0 obj<</Parent 1176 0 R/Title(2.3.6. Test 6)/Dest[822 0 R/XYZ null 275 null]/Prev 1184 0 R/Next 1186 0 R>>endobj
-1186 0 obj<</Parent 1176 0 R/Title(2.3.7. Test 7)/Dest[825 0 R/XYZ null 669 null]/Prev 1185 0 R/Next 1187 0 R>>endobj
-1187 0 obj<</Parent 1176 0 R/Title(2.3.8. Test 8)/Dest[825 0 R/XYZ null 294 null]/Prev 1186 0 R/Next 1188 0 R>>endobj
-1188 0 obj<</Parent 1176 0 R/Title(2.3.9. Test 9)/Dest[828 0 R/XYZ null 603 null]/Prev 1187 0 R/Next 1189 0 R>>endobj
-1189 0 obj<</Parent 1176 0 R/Title(2.3.10. Test 10)/Dest[828 0 R/XYZ null 426 null]/Prev 1188 0 R/Next 1190 0 R>>endobj
-1190 0 obj<</Parent 1176 0 R/Title(2.3.11. Test 11)/Dest[828 0 R/XYZ null 275 null]/Prev 1189 0 R/Next 1191 0 R>>endobj
-1191 0 obj<</Parent 1176 0 R/Title(2.4. Still having troubles?)/Dest[831 0 R/XYZ null 750 null]/Prev 1190 0 R>>endobj
-1192 0 obj<</Parent 1155 0 R/Count -18/First 1193 0 R/Last 1210 0 R/Title(Chapter 3. Integrating MS Windows networks with Samba)/Dest[834 0 R/XYZ null 750 null]/Prev 1176 0 R/Next 1211 0 R>>endobj
-1193 0 obj<</Parent 1192 0 R/Title(3.1. Agenda)/Dest[834 0 R/XYZ null 702 null]/Next 1194 0 R>>endobj
-1194 0 obj<</Parent 1192 0 R/Title(3.2. Name Resolution in a pure Unix/Linux world)/Dest[834 0 R/XYZ null 459 null]/Prev 1193 0 R/Next 1195 0 R>>endobj
-1195 0 obj<</Parent 1192 0 R/Title(3.2.1. /etc/hosts)/Dest[834 0 R/XYZ null 321 null]/Prev 1194 0 R/Next 1196 0 R>>endobj
-1196 0 obj<</Parent 1192 0 R/Title(3.2.2. /etc/resolv.conf)/Dest[837 0 R/XYZ null 431 null]/Prev 1195 0 R/Next 1197 0 R>>endobj
-1197 0 obj<</Parent 1192 0 R/Title(3.2.3. /etc/host.conf)/Dest[837 0 R/XYZ null 281 null]/Prev 1196 0 R/Next 1198 0 R>>endobj
-1198 0 obj<</Parent 1192 0 R/Title(3.2.4. /etc/nsswitch.conf)/Dest[840 0 R/XYZ null 750 null]/Prev 1197 0 R/Next 1199 0 R>>endobj
-1199 0 obj<</Parent 1192 0 R/Title(3.3. Name resolution as used within MS Windows networking)/Dest[840 0 R/XYZ null 264 null]/Prev 1198 0 R/Next 1200 0 R>>endobj
-1200 0 obj<</Parent 1192 0 R/Title(3.3.1. The NetBIOS Name Cache)/Dest[843 0 R/XYZ null 206 null]/Prev 1199 0 R/Next 1201 0 R>>endobj
-1201 0 obj<</Parent 1192 0 R/Title(3.3.2. The LMHOSTS file)/Dest[846 0 R/XYZ null 656 null]/Prev 1200 0 R/Next 1202 0 R>>endobj
-1202 0 obj<</Parent 1192 0 R/Title(3.3.3. HOSTS file)/Dest[849 0 R/XYZ null 367 null]/Prev 1201 0 R/Next 1203 0 R>>endobj
-1203 0 obj<</Parent 1192 0 R/Title(3.3.4. DNS Lookup)/Dest[849 0 R/XYZ null 256 null]/Prev 1202 0 R/Next 1204 0 R>>endobj
-1204 0 obj<</Parent 1192 0 R/Title(3.3.5. WINS Lookup)/Dest[852 0 R/XYZ null 750 null]/Prev 1203 0 R/Next 1205 0 R>>endobj
-1205 0 obj<</Parent 1192 0 R/Title(3.4. How browsing functions and how to deploy stable and dependable browsing using Samba)/Dest[852 0 R/XYZ null 525 null]/Prev 1204 0 R/Next 1206 0 R>>endobj
-1206 0 obj<</Parent 1192 0 R/Title(3.5. MS Windows security options and how to configure Samba for seemless integration)/Dest[855 0 R/XYZ null 629 null]/Prev 1205 0 R/Next 1207 0 R>>endobj
-1207 0 obj<</Parent 1192 0 R/Title(3.5.1. Use MS Windows NT as an authentication server)/Dest[858 0 R/XYZ null 577 null]/Prev 1206 0 R/Next 1208 0 R>>endobj
-1208 0 obj<</Parent 1192 0 R/Title(3.5.2. Make Samba a member of an MS Windows NT security domain)/Dest[858 0 R/XYZ null 300 null]/Prev 1207 0 R/Next 1209 0 R>>endobj
-1209 0 obj<</Parent 1192 0 R/Title(3.5.3. Configure Samba as an authentication server)/Dest[861 0 R/XYZ null 590 null]/Prev 1208 0 R/Next 1210 0 R>>endobj
-1210 0 obj<</Parent 1192 0 R/Title(3.6. Conclusions)/Dest[864 0 R/XYZ null 635 null]/Prev 1209 0 R>>endobj
-1211 0 obj<</Parent 1155 0 R/Count -3/First 1212 0 R/Last 1214 0 R/Title(Chapter 4. Configuring PAM for distributed but centrally managed authentication)/Dest[867 0 R/XYZ null 750 null]/Prev 1192 0 R/Next 1215 0 R>>endobj
-1212 0 obj<</Parent 1211 0 R/Title(4.1. Samba and PAM)/Dest[867 0 R/XYZ null 702 null]/Next 1213 0 R>>endobj
-1213 0 obj<</Parent 1211 0 R/Title(4.2. Distributed Authentication)/Dest[870 0 R/XYZ null 175 null]/Prev 1212 0 R/Next 1214 0 R>>endobj
-1214 0 obj<</Parent 1211 0 R/Title(4.3. PAM Configuration in smb.conf)/Dest[873 0 R/XYZ null 722 null]/Prev 1213 0 R>>endobj
-1215 0 obj<</Parent 1155 0 R/Count -2/First 1216 0 R/Last 1217 0 R/Title(Chapter 5. Hosting a Microsoft Distributed File System tree on Samba)/Dest[876 0 R/XYZ null 750 null]/Prev 1211 0 R/Next 1218 0 R>>endobj
-1216 0 obj<</Parent 1215 0 R/Title(5.1. Instructions)/Dest[876 0 R/XYZ null 702 null]/Next 1217 0 R>>endobj
-1217 0 obj<</Parent 1215 0 R/Title(5.1.1. Notes)/Dest[879 0 R/XYZ null 669 null]/Prev 1216 0 R>>endobj
-1218 0 obj<</Parent 1155 0 R/Count -9/First 1219 0 R/Last 1227 0 R/Title(Chapter 6. UNIX Permission Bits and Windows NT Access Control Lists)/Dest[882 0 R/XYZ null 750 null]/Prev 1215 0 R/Next 1228 0 R>>endobj
-1219 0 obj<</Parent 1218 0 R/Title(6.1. Viewing and changing UNIX permissions using the NT security dialogs)/Dest[882 0 R/XYZ null 702 null]/Next 1220 0 R>>endobj
-1220 0 obj<</Parent 1218 0 R/Title(6.2. How to view file security on a Samba share)/Dest[882 0 R/XYZ null 521 null]/Prev 1219 0 R/Next 1221 0 R>>endobj
-1221 0 obj<</Parent 1218 0 R/Title(6.3. Viewing file ownership)/Dest[882 0 R/XYZ null 344 null]/Prev 1220 0 R/Next 1222 0 R>>endobj
-1222 0 obj<</Parent 1218 0 R/Title(6.4. Viewing file or directory permissions)/Dest[885 0 R/XYZ null 682 null]/Prev 1221 0 R/Next 1223 0 R>>endobj
-1223 0 obj<</Parent 1218 0 R/Title(6.4.1. File Permissions)/Dest[885 0 R/XYZ null 439 null]/Prev 1222 0 R/Next 1224 0 R>>endobj
-1224 0 obj<</Parent 1218 0 R/Title(6.4.2. Directory Permissions)/Dest[885 0 R/XYZ null 183 null]/Prev 1223 0 R/Next 1225 0 R>>endobj
-1225 0 obj<</Parent 1218 0 R/Title(6.5. Modifying file or directory permissions)/Dest[888 0 R/XYZ null 669 null]/Prev 1224 0 R/Next 1226 0 R>>endobj
-1226 0 obj<</Parent 1218 0 R/Title(6.6. Interaction with the standard Samba create mask parameters)/Dest[888 0 R/XYZ null 228 null]/Prev 1225 0 R/Next 1227 0 R>>endobj
-1227 0 obj<</Parent 1218 0 R/Title(6.7. Interaction with the standard Samba file attribute mapping)/Dest[894 0 R/XYZ null 590 null]/Prev 1226 0 R>>endobj
-1228 0 obj<</Parent 1155 0 R/Count -13/First 1229 0 R/Last 1241 0 R/Title(Chapter 7. Printing Support in Samba 2.2.x)/Dest[897 0 R/XYZ null 750 null]/Prev 1218 0 R/Next 1242 0 R>>endobj
-1229 0 obj<</Parent 1228 0 R/Title(7.1. Introduction)/Dest[897 0 R/XYZ null 726 null]/Next 1230 0 R>>endobj
-1230 0 obj<</Parent 1228 0 R/Title(7.2. Configuration)/Dest[897 0 R/XYZ null 298 null]/Prev 1229 0 R/Next 1231 0 R>>endobj
-1231 0 obj<</Parent 1228 0 R/Title(7.2.1. Creating [print$])/Dest[900 0 R/XYZ null 689 null]/Prev 1230 0 R/Next 1232 0 R>>endobj
-1232 0 obj<</Parent 1228 0 R/Title(7.2.2. Setting Drivers for Existing Printers)/Dest[903 0 R/XYZ null 446 null]/Prev 1231 0 R/Next 1233 0 R>>endobj
-1233 0 obj<</Parent 1228 0 R/Title(7.2.3. Support a large number of printers)/Dest[906 0 R/XYZ null 682 null]/Prev 1232 0 R/Next 1234 0 R>>endobj
-1234 0 obj<</Parent 1228 0 R/Title(7.2.4. Adding New Printers via the Windows NT APW)/Dest[906 0 R/XYZ null 298 null]/Prev 1233 0 R/Next 1235 0 R>>endobj
-1235 0 obj<</Parent 1228 0 R/Title(7.2.5. Samba and Printer Ports)/Dest[909 0 R/XYZ null 682 null]/Prev 1234 0 R/Next 1236 0 R>>endobj
-1236 0 obj<</Parent 1228 0 R/Title(7.3. The Imprints Toolset)/Dest[909 0 R/XYZ null 492 null]/Prev 1235 0 R/Next 1237 0 R>>endobj
-1237 0 obj<</Parent 1228 0 R/Title(7.3.1. What is Imprints?)/Dest[909 0 R/XYZ null 381 null]/Prev 1236 0 R/Next 1238 0 R>>endobj
-1238 0 obj<</Parent 1228 0 R/Title(7.3.2. Creating Printer Driver Packages)/Dest[909 0 R/XYZ null 243 null]/Prev 1237 0 R/Next 1239 0 R>>endobj
-1239 0 obj<</Parent 1228 0 R/Title(7.3.3. The Imprints server)/Dest[909 0 R/XYZ null 145 null]/Prev 1238 0 R/Next 1240 0 R>>endobj
-1240 0 obj<</Parent 1228 0 R/Title(7.3.4. The Installation Client)/Dest[912 0 R/XYZ null 709 null]/Prev 1239 0 R/Next 1241 0 R>>endobj
-1241 0 obj<</Parent 1228 0 R/Title(7.4. Migration to from Samba 2.0.x to 2.2.x)/Dest[915 0 R/XYZ null 750 null]/Prev 1240 0 R>>endobj
-1242 0 obj<</Parent 1155 0 R/Count -9/First 1243 0 R/Last 1251 0 R/Title(Chapter 8. Debugging Printing Problems)/Dest[918 0 R/XYZ null 750 null]/Prev 1228 0 R/Next 1252 0 R>>endobj
-1243 0 obj<</Parent 1242 0 R/Title(8.1. Introduction)/Dest[918 0 R/XYZ null 726 null]/Next 1244 0 R>>endobj
-1244 0 obj<</Parent 1242 0 R/Title(8.2. Debugging printer problems)/Dest[921 0 R/XYZ null 750 null]/Prev 1243 0 R/Next 1245 0 R>>endobj
-1245 0 obj<</Parent 1242 0 R/Title(8.3. What printers do I have?)/Dest[921 0 R/XYZ null 296 null]/Prev 1244 0 R/Next 1246 0 R>>endobj
-1246 0 obj<</Parent 1242 0 R/Title(8.4. Setting up printcap and print servers)/Dest[924 0 R/XYZ null 750 null]/Prev 1245 0 R/Next 1247 0 R>>endobj
-1247 0 obj<</Parent 1242 0 R/Title(8.5. Job sent, no output)/Dest[924 0 R/XYZ null 323 null]/Prev 1246 0 R/Next 1248 0 R>>endobj
-1248 0 obj<</Parent 1242 0 R/Title(8.6. Job sent, strange output)/Dest[927 0 R/XYZ null 635 null]/Prev 1247 0 R/Next 1249 0 R>>endobj
-1249 0 obj<</Parent 1242 0 R/Title(8.7. Raw PostScript printed)/Dest[927 0 R/XYZ null 276 null]/Prev 1248 0 R/Next 1250 0 R>>endobj
-1250 0 obj<</Parent 1242 0 R/Title(8.8. Advanced Printing)/Dest[927 0 R/XYZ null 178 null]/Prev 1249 0 R/Next 1251 0 R>>endobj
-1251 0 obj<</Parent 1242 0 R/Title(8.9. Real debugging)/Dest[930 0 R/XYZ null 735 null]/Prev 1250 0 R>>endobj
-1252 0 obj<</Parent 1155 0 R/Count -2/First 1253 0 R/Last 1254 0 R/Title(Chapter 9. Security levels)/Dest[933 0 R/XYZ null 750 null]/Prev 1242 0 R/Next 1255 0 R>>endobj
-1253 0 obj<</Parent 1252 0 R/Title(9.1. Introduction)/Dest[933 0 R/XYZ null 726 null]/Next 1254 0 R>>endobj
-1254 0 obj<</Parent 1252 0 R/Title(9.2. More complete description of security levels)/Dest[933 0 R/XYZ null 487 null]/Prev 1253 0 R>>endobj
-1255 0 obj<</Parent 1155 0 R/Count -3/First 1256 0 R/Last 1258 0 R/Title(Chapter 10. security = domain in Samba 2.x)/Dest[939 0 R/XYZ null 750 null]/Prev 1252 0 R/Next 1259 0 R>>endobj
-1256 0 obj<</Parent 1255 0 R/Title(10.1. Joining an NT Domain with Samba 2.2)/Dest[939 0 R/XYZ null 726 null]/Next 1257 0 R>>endobj
-1257 0 obj<</Parent 1255 0 R/Title(10.2. Samba and Windows 2000 Domains)/Dest[942 0 R/XYZ null 379 null]/Prev 1256 0 R/Next 1258 0 R>>endobj
-1258 0 obj<</Parent 1255 0 R/Title(10.3. Why is this better than security = server?)/Dest[942 0 R/XYZ null 162 null]/Prev 1257 0 R>>endobj
-1259 0 obj<</Parent 1155 0 R/Count -16/First 1260 0 R/Last 1275 0 R/Title(Chapter 11. Unified Logons between Windows NT and UNIX using Winbind)/Dest[948 0 R/XYZ null 750 null]/Prev 1255 0 R/Next 1276 0 R>>endobj
-1260 0 obj<</Parent 1259 0 R/Title(11.1. Abstract)/Dest[948 0 R/XYZ null 702 null]/Next 1261 0 R>>endobj
-1261 0 obj<</Parent 1259 0 R/Title(11.2. Introduction)/Dest[948 0 R/XYZ null 565 null]/Prev 1260 0 R/Next 1262 0 R>>endobj
-1262 0 obj<</Parent 1259 0 R/Title(11.3. What Winbind Provides)/Dest[948 0 R/XYZ null 242 null]/Prev 1261 0 R/Next 1263 0 R>>endobj
-1263 0 obj<</Parent 1259 0 R/Title(11.3.1. Target Uses)/Dest[951 0 R/XYZ null 577 null]/Prev 1262 0 R/Next 1264 0 R>>endobj
-1264 0 obj<</Parent 1259 0 R/Title(11.4. How Winbind Works)/Dest[951 0 R/XYZ null 413 null]/Prev 1263 0 R/Next 1265 0 R>>endobj
-1265 0 obj<</Parent 1259 0 R/Title(11.4.1. Microsoft Remote Procedure Calls)/Dest[951 0 R/XYZ null 288 null]/Prev 1264 0 R/Next 1266 0 R>>endobj
-1266 0 obj<</Parent 1259 0 R/Title(11.4.2. Name Service Switch)/Dest[954 0 R/XYZ null 750 null]/Prev 1265 0 R/Next 1267 0 R>>endobj
-1267 0 obj<</Parent 1259 0 R/Title(11.4.3. Pluggable Authentication Modules)/Dest[954 0 R/XYZ null 309 null]/Prev 1266 0 R/Next 1268 0 R>>endobj
-1268 0 obj<</Parent 1259 0 R/Title(11.4.4. User and Group ID Allocation)/Dest[957 0 R/XYZ null 669 null]/Prev 1267 0 R/Next 1269 0 R>>endobj
-1269 0 obj<</Parent 1259 0 R/Title(11.4.5. Result Caching)/Dest[957 0 R/XYZ null 479 null]/Prev 1268 0 R/Next 1270 0 R>>endobj
-1270 0 obj<</Parent 1259 0 R/Title(11.5. Installation and Configuration)/Dest[957 0 R/XYZ null 328 null]/Prev 1269 0 R/Next 1271 0 R>>endobj
-1271 0 obj<</Parent 1259 0 R/Title(11.5.1. Introduction)/Dest[957 0 R/XYZ null 177 null]/Prev 1270 0 R/Next 1272 0 R>>endobj
-1272 0 obj<</Parent 1259 0 R/Title(11.5.2. Requirements)/Dest[960 0 R/XYZ null 537 null]/Prev 1271 0 R/Next 1273 0 R>>endobj
-1273 0 obj<</Parent 1259 0 R/Title(11.5.3. Testing Things Out)/Dest[960 0 R/XYZ null 254 null]/Prev 1272 0 R/Next 1274 0 R>>endobj
-1274 0 obj<</Parent 1259 0 R/Title(11.6. Limitations)/Dest[984 0 R/XYZ null 614 null]/Prev 1273 0 R/Next 1275 0 R>>endobj
-1275 0 obj<</Parent 1259 0 R/Title(11.7. Conclusion)/Dest[984 0 R/XYZ null 397 null]/Prev 1274 0 R>>endobj
-1276 0 obj<</Parent 1155 0 R/Count -14/First 1277 0 R/Last 1290 0 R/Title(Chapter 12. How to Configure Samba 2.2 as a Primary Domain Controller)/Dest[987 0 R/XYZ null 750 null]/Prev 1259 0 R/Next 1291 0 R>>endobj
-1277 0 obj<</Parent 1276 0 R/Title(12.1. Prerequisite Reading)/Dest[987 0 R/XYZ null 702 null]/Next 1278 0 R>>endobj
-1278 0 obj<</Parent 1276 0 R/Title(12.2. Background)/Dest[987 0 R/XYZ null 604 null]/Prev 1277 0 R/Next 1279 0 R>>endobj
-1279 0 obj<</Parent 1276 0 R/Title(12.3. Configuring the Samba Domain Controller)/Dest[990 0 R/XYZ null 722 null]/Prev 1278 0 R/Next 1280 0 R>>endobj
-1280 0 obj<</Parent 1276 0 R/Title(12.4. Creating Machine Trust Accounts and Joining Clients to the Domain)/Dest[993 0 R/XYZ null 603 null]/Prev 1279 0 R/Next 1281 0 R>>endobj
-1281 0 obj<</Parent 1276 0 R/Title(12.4.1. Manual Creation of Machine Trust Accounts)/Dest[993 0 R/XYZ null 211 null]/Prev 1280 0 R/Next 1282 0 R>>endobj
-1282 0 obj<</Parent 1276 0 R/Title(12.4.2. "On-the-Fly" Creation of Machine Trust Accounts)/Dest[996 0 R/XYZ null 328 null]/Prev 1281 0 R/Next 1283 0 R>>endobj
-1283 0 obj<</Parent 1276 0 R/Title(12.4.3. Joining the Client to the Domain)/Dest[999 0 R/XYZ null 750 null]/Prev 1282 0 R/Next 1284 0 R>>endobj
-1284 0 obj<</Parent 1276 0 R/Title(12.5. Common Problems and Errors)/Dest[999 0 R/XYZ null 388 null]/Prev 1283 0 R/Next 1285 0 R>>endobj
-1285 0 obj<</Parent 1276 0 R/Title(12.6. System Policies and Profiles)/Dest[1005 0 R/XYZ null 735 null]/Prev 1284 0 R/Next 1286 0 R>>endobj
-1286 0 obj<</Parent 1276 0 R/Title(12.7. What other help can I get?)/Dest[1008 0 R/XYZ null 682 null]/Prev 1285 0 R/Next 1287 0 R>>endobj
-1287 0 obj<</Parent 1276 0 R/Title(12.8. Domain Control for Windows 9x/ME)/Dest[1014 0 R/XYZ null 299 null]/Prev 1286 0 R/Next 1288 0 R>>endobj
-1288 0 obj<</Parent 1276 0 R/Title(12.8.1. Configuration Instructions: Network Logons)/Dest[1017 0 R/XYZ null 273 null]/Prev 1287 0 R/Next 1289 0 R>>endobj
-1289 0 obj<</Parent 1276 0 R/Title(12.8.2. Configuration Instructions: Setting up Roaming User Profiles)/Dest[1020 0 R/XYZ null 478 null]/Prev 1288 0 R/Next 1290 0 R>>endobj
-1290 0 obj<</Parent 1276 0 R/Title(12.9. DOMAIN_CONTROL.txt : Windows NT Domain Control & Samba)/Dest[1032 0 R/XYZ null 270 null]/Prev 1289 0 R>>endobj
-1291 0 obj<</Parent 1155 0 R/Count -8/First 1292 0 R/Last 1299 0 R/Title(Chapter 13. How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain)/Dest[1041 0 R/XYZ null 750 null]/Prev 1276 0 R/Next 1300 0 R>>endobj
-1292 0 obj<</Parent 1291 0 R/Title(13.1. Prerequisite Reading)/Dest[1041 0 R/XYZ null 702 null]/Next 1293 0 R>>endobj
-1293 0 obj<</Parent 1291 0 R/Title(13.2. Background)/Dest[1041 0 R/XYZ null 617 null]/Prev 1292 0 R/Next 1294 0 R>>endobj
-1294 0 obj<</Parent 1291 0 R/Title(13.3. What qualifies a Domain Controller on the network?)/Dest[1041 0 R/XYZ null 235 null]/Prev 1293 0 R/Next 1295 0 R>>endobj
-1295 0 obj<</Parent 1291 0 R/Title(13.3.1. How does a Workstation find its domain controller?)/Dest[1044 0 R/XYZ null 750 null]/Prev 1294 0 R/Next 1296 0 R>>endobj
-1296 0 obj<</Parent 1291 0 R/Title(13.3.2. When is the PDC needed?)/Dest[1044 0 R/XYZ null 626 null]/Prev 1295 0 R/Next 1297 0 R>>endobj
-1297 0 obj<</Parent 1291 0 R/Title(13.4. Can Samba be a Backup Domain Controller?)/Dest[1044 0 R/XYZ null 528 null]/Prev 1296 0 R/Next 1298 0 R>>endobj
-1298 0 obj<</Parent 1291 0 R/Title(13.5. How do I set up a Samba BDC?)/Dest[1044 0 R/XYZ null 377 null]/Prev 1297 0 R/Next 1299 0 R>>endobj
-1299 0 obj<</Parent 1291 0 R/Title(13.5.1. How do I replicate the smbpasswd file?)/Dest[1047 0 R/XYZ null 646 null]/Prev 1298 0 R>>endobj
-1300 0 obj<</Parent 1155 0 R/Count -12/First 1301 0 R/Last 1312 0 R/Title(Chapter 14. Storing Samba's User/Machine Account information in an LDAP Directory)/Dest[1050 0 R/XYZ null 750 null]/Prev 1291 0 R/Next 1313 0 R>>endobj
-1301 0 obj<</Parent 1300 0 R/Title(14.1. Purpose)/Dest[1050 0 R/XYZ null 702 null]/Next 1302 0 R>>endobj
-1302 0 obj<</Parent 1300 0 R/Title(14.2. Introduction)/Dest[1050 0 R/XYZ null 433 null]/Prev 1301 0 R/Next 1303 0 R>>endobj
-1303 0 obj<</Parent 1300 0 R/Title(14.3. Supported LDAP Servers)/Dest[1053 0 R/XYZ null 577 null]/Prev 1302 0 R/Next 1304 0 R>>endobj
-1304 0 obj<</Parent 1300 0 R/Title(14.4. Schema and Relationship to the RFC 2307 posixAccount)/Dest[1053 0 R/XYZ null 465 null]/Prev 1303 0 R/Next 1305 0 R>>endobj
-1305 0 obj<</Parent 1300 0 R/Title(14.5. Configuring Samba with LDAP)/Dest[1056 0 R/XYZ null 735 null]/Prev 1304 0 R/Next 1306 0 R>>endobj
-1306 0 obj<</Parent 1300 0 R/Title(14.5.1. OpenLDAP configuration)/Dest[1056 0 R/XYZ null 705 null]/Prev 1305 0 R/Next 1307 0 R>>endobj
-1307 0 obj<</Parent 1300 0 R/Title(14.5.2. Configuring Samba)/Dest[1059 0 R/XYZ null 750 null]/Prev 1306 0 R/Next 1308 0 R>>endobj
-1308 0 obj<</Parent 1300 0 R/Title(14.6. Accounts and Groups management)/Dest[1059 0 R/XYZ null 176 null]/Prev 1307 0 R/Next 1309 0 R>>endobj
-1309 0 obj<</Parent 1300 0 R/Title(14.7. Security and sambaAccount)/Dest[1062 0 R/XYZ null 629 null]/Prev 1308 0 R/Next 1310 0 R>>endobj
-1310 0 obj<</Parent 1300 0 R/Title(14.8. LDAP specials attributes for sambaAccounts)/Dest[1062 0 R/XYZ null 236 null]/Prev 1309 0 R/Next 1311 0 R>>endobj
-1311 0 obj<</Parent 1300 0 R/Title(14.9. Example LDIF Entries for a sambaAccount)/Dest[1065 0 R/XYZ null 207 null]/Prev 1310 0 R/Next 1312 0 R>>endobj
-1312 0 obj<</Parent 1300 0 R/Title(14.10. Comments)/Dest[1068 0 R/XYZ null 358 null]/Prev 1311 0 R>>endobj
-1313 0 obj<</Parent 1155 0 R/Count -12/First 1314 0 R/Last 1325 0 R/Title(Chapter 15. Improved browsing in samba)/Dest[1071 0 R/XYZ null 750 null]/Prev 1300 0 R/Next 1326 0 R>>endobj
-1314 0 obj<</Parent 1313 0 R/Title(15.1. Overview of browsing)/Dest[1071 0 R/XYZ null 726 null]/Next 1315 0 R>>endobj
-1315 0 obj<</Parent 1313 0 R/Title(15.2. Browsing support in samba)/Dest[1071 0 R/XYZ null 536 null]/Prev 1314 0 R/Next 1316 0 R>>endobj
-1316 0 obj<</Parent 1313 0 R/Title(15.3. Problem resolution)/Dest[1074 0 R/XYZ null 750 null]/Prev 1315 0 R/Next 1317 0 R>>endobj
-1317 0 obj<</Parent 1313 0 R/Title(15.4. Browsing across subnets)/Dest[1074 0 R/XYZ null 467 null]/Prev 1316 0 R/Next 1318 0 R>>endobj
-1318 0 obj<</Parent 1313 0 R/Title(15.4.1. How does cross subnet browsing work ?)/Dest[1074 0 R/XYZ null 198 null]/Prev 1317 0 R/Next 1319 0 R>>endobj
-1319 0 obj<</Parent 1313 0 R/Title(15.5. Setting up a WINS server)/Dest[1083 0 R/XYZ null 443 null]/Prev 1318 0 R/Next 1320 0 R>>endobj
-1320 0 obj<</Parent 1313 0 R/Title(15.6. Setting up Browsing in a WORKGROUP)/Dest[1086 0 R/XYZ null 484 null]/Prev 1319 0 R/Next 1321 0 R>>endobj
-1321 0 obj<</Parent 1313 0 R/Title(15.7. Setting up Browsing in a DOMAIN)/Dest[1089 0 R/XYZ null 488 null]/Prev 1320 0 R/Next 1322 0 R>>endobj
-1322 0 obj<</Parent 1313 0 R/Title(15.8. Forcing samba to be the master)/Dest[1092 0 R/XYZ null 750 null]/Prev 1321 0 R/Next 1323 0 R>>endobj
-1323 0 obj<</Parent 1313 0 R/Title(15.9. Making samba the domain master)/Dest[1092 0 R/XYZ null 335 null]/Prev 1322 0 R/Next 1324 0 R>>endobj
-1324 0 obj<</Parent 1313 0 R/Title(15.10. Note about broadcast addresses)/Dest[1095 0 R/XYZ null 563 null]/Prev 1323 0 R/Next 1325 0 R>>endobj
-1325 0 obj<</Parent 1313 0 R/Title(15.11. Multiple interfaces)/Dest[1095 0 R/XYZ null 465 null]/Prev 1324 0 R>>endobj
-1326 0 obj<</Parent 1155 0 R/Count -20/First 1327 0 R/Last 1346 0 R/Title(Chapter 16. Samba performance issues)/Dest[1098 0 R/XYZ null 750 null]/Prev 1313 0 R/Next 1347 0 R>>endobj
-1327 0 obj<</Parent 1326 0 R/Title(16.1. Comparisons)/Dest[1098 0 R/XYZ null 726 null]/Next 1328 0 R>>endobj
-1328 0 obj<</Parent 1326 0 R/Title(16.2. Oplocks)/Dest[1098 0 R/XYZ null 470 null]/Prev 1327 0 R/Next 1329 0 R>>endobj
-1329 0 obj<</Parent 1326 0 R/Title(16.2.1. Overview)/Dest[1098 0 R/XYZ null 440 null]/Prev 1328 0 R/Next 1330 0 R>>endobj
-1330 0 obj<</Parent 1326 0 R/Title(16.2.2. Level2 Oplocks)/Dest[1098 0 R/XYZ null 157 null]/Prev 1329 0 R/Next 1331 0 R>>endobj
-1331 0 obj<</Parent 1326 0 R/Title(16.2.3. Old 'fake oplocks' option - deprecated)/Dest[1101 0 R/XYZ null 643 null]/Prev 1330 0 R/Next 1332 0 R>>endobj
-1332 0 obj<</Parent 1326 0 R/Title(16.3. Socket options)/Dest[1101 0 R/XYZ null 479 null]/Prev 1331 0 R/Next 1333 0 R>>endobj
-1333 0 obj<</Parent 1326 0 R/Title(16.4. Read size)/Dest[1101 0 R/XYZ null 209 null]/Prev 1332 0 R/Next 1334 0 R>>endobj
-1334 0 obj<</Parent 1326 0 R/Title(16.5. Max xmit)/Dest[1104 0 R/XYZ null 656 null]/Prev 1333 0 R/Next 1335 0 R>>endobj
-1335 0 obj<</Parent 1326 0 R/Title(16.6. Locking)/Dest[1104 0 R/XYZ null 465 null]/Prev 1334 0 R/Next 1336 0 R>>endobj
-1336 0 obj<</Parent 1326 0 R/Title(16.7. Share modes)/Dest[1104 0 R/XYZ null 328 null]/Prev 1335 0 R/Next 1337 0 R>>endobj
-1337 0 obj<</Parent 1326 0 R/Title(16.8. Log level)/Dest[1107 0 R/XYZ null 750 null]/Prev 1336 0 R/Next 1338 0 R>>endobj
-1338 0 obj<</Parent 1326 0 R/Title(16.9. Wide lines)/Dest[1107 0 R/XYZ null 679 null]/Prev 1337 0 R/Next 1339 0 R>>endobj
-1339 0 obj<</Parent 1326 0 R/Title(16.10. Read raw)/Dest[1107 0 R/XYZ null 581 null]/Prev 1338 0 R/Next 1340 0 R>>endobj
-1340 0 obj<</Parent 1326 0 R/Title(16.11. Write raw)/Dest[1107 0 R/XYZ null 403 null]/Prev 1339 0 R/Next 1341 0 R>>endobj
-1341 0 obj<</Parent 1326 0 R/Title(16.12. Read prediction)/Dest[1107 0 R/XYZ null 266 null]/Prev 1340 0 R/Next 1342 0 R>>endobj
-1342 0 obj<</Parent 1326 0 R/Title(16.13. Memory mapping)/Dest[1110 0 R/XYZ null 709 null]/Prev 1341 0 R/Next 1343 0 R>>endobj
-1343 0 obj<</Parent 1326 0 R/Title(16.14. Slow Clients)/Dest[1110 0 R/XYZ null 531 null]/Prev 1342 0 R/Next 1344 0 R>>endobj
-1344 0 obj<</Parent 1326 0 R/Title(16.15. Slow Logins)/Dest[1110 0 R/XYZ null 394 null]/Prev 1343 0 R/Next 1345 0 R>>endobj
-1345 0 obj<</Parent 1326 0 R/Title(16.16. Client tuning)/Dest[1110 0 R/XYZ null 309 null]/Prev 1344 0 R/Next 1346 0 R>>endobj
-1346 0 obj<</Parent 1326 0 R/Title(16.17. My Results)/Dest[1113 0 R/XYZ null 260 null]/Prev 1345 0 R>>endobj
-1347 0 obj<</Parent 1155 0 R/Count -5/First 1348 0 R/Last 1352 0 R/Title(Chapter 17. OS2 Client HOWTO)/Dest[1119 0 R/XYZ null 750 null]/Prev 1326 0 R/Next 1353 0 R>>endobj
-1348 0 obj<</Parent 1347 0 R/Title(17.1. FAQs)/Dest[1119 0 R/XYZ null 726 null]/Next 1349 0 R>>endobj
-1349 0 obj<</Parent 1347 0 R/Title(17.1.1. How can I configure OS/2 Warp Connect or OS/2 Warp 4 as a client for Samba?)/Dest[1119 0 R/XYZ null 696 null]/Prev 1348 0 R/Next 1350 0 R>>endobj
-1350 0 obj<</Parent 1347 0 R/Title(17.1.2. How can I configure OS/2 Warp 3 \(not Connect\), OS/2 1.2, 1.3 or 2.x for Samba?)/Dest[1119 0 R/XYZ null 344 null]/Prev 1349 0 R/Next 1351 0 R>>endobj
-1351 0 obj<</Parent 1347 0 R/Title(17.1.3. Are there any other issues when OS/2 \(any version\) is used as a client?)/Dest[1122 0 R/XYZ null 750 null]/Prev 1350 0 R/Next 1352 0 R>>endobj
-1352 0 obj<</Parent 1347 0 R/Title(17.1.4. How do I get printer driver download working for OS/2 clients?)/Dest[1122 0 R/XYZ null 635 null]/Prev 1351 0 R>>endobj
-1353 0 obj<</Parent 1155 0 R/Count -4/First 1354 0 R/Last 1357 0 R/Title(Chapter 18. HOWTO Access Samba source code via CVS)/Dest[1125 0 R/XYZ null 750 null]/Prev 1347 0 R/Next 1358 0 R>>endobj
-1354 0 obj<</Parent 1353 0 R/Title(18.1. Introduction)/Dest[1125 0 R/XYZ null 702 null]/Next 1355 0 R>>endobj
-1355 0 obj<</Parent 1353 0 R/Title(18.2. CVS Access to samba.org)/Dest[1125 0 R/XYZ null 578 null]/Prev 1354 0 R/Next 1356 0 R>>endobj
-1356 0 obj<</Parent 1353 0 R/Title(18.2.1. Access via CVSweb)/Dest[1125 0 R/XYZ null 480 null]/Prev 1355 0 R/Next 1357 0 R>>endobj
-1357 0 obj<</Parent 1353 0 R/Title(18.2.2. Access via cvs)/Dest[1125 0 R/XYZ null 355 null]/Prev 1356 0 R>>endobj
-1358 0 obj<</Parent 1155 0 R/Count -6/First 1359 0 R/Last 1364 0 R/Title(Chapter 19. Reporting Bugs)/Dest[1131 0 R/XYZ null 750 null]/Prev 1353 0 R/Next 1365 0 R>>endobj
-1359 0 obj<</Parent 1358 0 R/Title(19.1. Introduction)/Dest[1131 0 R/XYZ null 726 null]/Next 1360 0 R>>endobj
-1360 0 obj<</Parent 1358 0 R/Title(19.2. General info)/Dest[1131 0 R/XYZ null 457 null]/Prev 1359 0 R/Next 1361 0 R>>endobj
-1361 0 obj<</Parent 1358 0 R/Title(19.3. Debug levels)/Dest[1131 0 R/XYZ null 306 null]/Prev 1360 0 R/Next 1362 0 R>>endobj
-1362 0 obj<</Parent 1358 0 R/Title(19.4. Internal errors)/Dest[1134 0 R/XYZ null 629 null]/Prev 1361 0 R/Next 1363 0 R>>endobj
-1363 0 obj<</Parent 1358 0 R/Title(19.5. Attaching to a running process)/Dest[1134 0 R/XYZ null 267 null]/Prev 1362 0 R/Next 1364 0 R>>endobj
-1364 0 obj<</Parent 1358 0 R/Title(19.6. Patches)/Dest[1134 0 R/XYZ null 156 null]/Prev 1363 0 R>>endobj
-1365 0 obj<</Parent 1155 0 R/Title(Index)/Dest[1137 0 R/XYZ null 722 null]/Prev 1358 0 R>>endobj
-1366 0 obj<</Type/Catalog/Pages 794 0 R/Names 556 0 R/PageLayout/SinglePage/Outlines 1155 0 R/OpenAction[795 0 R/XYZ null null null]/PageMode/UseOutlines/PageLabels<</Nums[0<</P(title)>>1<</S/r>>6<</S/D>>]>>>>endobj
+837 0 obj<</Type/Page/Parent 635 0 R/Contents 838 0 R/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>>>>>>endobj
+838 0 obj<</Length 839 0 R/Filter/FlateDecode>>stream
+x¥WMoÛF½ûW zrP[¶dGrzK‚0Ð8n­ =ä²"—âÖä.Ã%Ũ¿¾ïí’M‚"Ž“»óñæÍ›áד¹\âß\V ¹ZJRž¼[Ÿ\ܾ‘Å¥¬3¼Y®ndÊåìòO’Ó÷¹ª]Ë|>“OÖdF§ò‡Û:ëe£›Nk+ŸM]çå~ýjýÏÉ¥œ/®aâTÙT>Ýßý-­7vËSäú›ã ý_Íg ‡¸x»ñM­’&»†ÛþØbÅCw¶ÑÛZ5ÆYqY4O?LR;ï²fŒ4yíÚm.¢¤í#/¹äŠÁ#òi˜T×ÈIÉ/¹+öë¦ø¥Od~c3¸£‚Ûj«]ë7˪m˜—¶;S;[jÛxÉ\ K…ÃóÆ”z&ŸµTµöx)1¥eŸÒ©tc@†LOÏpŸÆåäØäZU¹Q“˜|k-<Q!®Z•^–ï
+†,î>Og7….Xô.¨ŽæµP)SVx ÇaŸ8=âü×Ã{ITQø3y(ÚíVÁ¬¼m­mLïpi[hœ`‰˜Ç½*ò£®w&AVi’œqÂŽë†ÒM\Þ¯%u¥B iíÃñªÒ
+@ê«4è
+8g¥y8kmBtUaš½˜†àï@!$™#<€Ð*3Û´:C`ˆ²Õ¹úÉ‹‡k(ö3¦úûúÍ&¯çoðûúf…ß ü¯ákèÍ¡W®o^>»M³˜ º¢Ô!0š¼¸èÄfŒëtQÈ“uØ‘«æý“«€MM–¡C@ÆÒ¥ºˆ¯uÏjâº0ÍIá¶è¾
+Ù¢'ÊÈBÁÓ#›NrëЖÕ`÷(Ø#ª†Êe…иRªThf’¶h@‰‰kBL™Ð¡fMç$–“à³EŽ§AWïö¬Õu¨áZ΂z}´š}X‚I‡ŽŠ„»Tí"þ&µ$ûQ[±àzÚc“$®¥<ÀØÆ5 <˜Øú5ôeÓ!àÀbÆ;A$vþ¸ñBÏCÉ ú@W5P”†½ÅÔšv€ÈïÀ÷
+H¡<fâå¨Òª´Ä@âžC#`‘á|XÛŽ°Ì@‚ƒìh„ÆD{”ÔÃÜëŸ Vˆ ÂS¯0ˆNß*ªÊhLjˆ‘É#´€Ãù@ññØ›¿YΖ?{óå</¥{WXa8ÂÀ#®•òÐÏáÈþà‡ù7‹õ»1ñPE™æ@PÛ°Éó º.”)Örã¾Qm¢œsY[¬J]n€6PPØŠûýe&-¶
+r}èPÈMü*Š[ê•Fù‰±ÍDÞéD! ss¶ÂxîE^€ŸŸæÜN"_NwF…ÈîÚ1ñòˆß
+endobj
+839 0 obj
+1670
+endobj
+840 0 obj<</Type/Page/Parent 635 0 R/Contents 841 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+841 0 obj<</Length 842 0 R/Filter/FlateDecode>>stream
+x…WMsÓH½çWtíÉT%Æ_$áhÈn-‡„,1‡\ZÒX"͘ÉZí¯ß×3’?IJ@ÖLw¿~ïuûûÅœfø5§›-¯)­.Þm.^ÿ±¢ùœ6[|r}{C›ŒfÓÙlF›tòÙ+çɪ EŸ>|¥ŠÓBE)‡‡†¯èa#9b“Qîl³#2\)OìådG­mÊ,¼ú›áZïÕoñ¶ðÖôÕæÛÅŒ®æËéÑ'9!÷§…m mu‰›È[\Åu¼"|¦2J:‰žÙŠuÈEÒu¤öÊPis<«åœ¢óì%QטQ`Ž/}½ú¢Mf[òÊ{âQŸ†^\OW}ÂÀ¨ìÈ&{mO8®SÔ€Cθ/Á3Òž¥M.H„ÿÅ’FØEèj~Q!ó­uÕ(Ñ»÷ëÏχƒ4< èOiS ~•¢vÔ kâ²´­?äl2U+WIGc.NeÚ©4æn‰G‘{ SkjgË=G”–Mz(pÚ±«uÚ”ì°/ ƒ Ý:-¨v—Wûkx8µUN™Tecl×Y¦%dÞ]ß9»×™ ÝiÐ_ƒ˜pðp¯Ó¡œH?z<–MžsR*ZŸUyo³FH÷<y\ß?¿"ß!ë
+Yê#£î5£ö#ñ&›Žpœ”‘€ïveŸ¥-…Mylj.uÝíå sç+²[äaÒÂY£ÿjï[ë2aUÝ*P>&êÉk`)Ý>yG4ãk‹‹9`AËzŸ'½ìhùó«Ð¤ß7ð z³œãçêö?øƒ(Ûh+oiyˆ­¬ÞÞie>Ÿ.§s À.W5}†ÔŒS/ºZˆMN´S‡—‘?$e]ÎÀ!ô\p£‚÷¨Ù©¿µ¯!ô#a‘ÚÀ7³uìA´ng EOLxΨ­öElyƒÅû€õ‹¯û »P þ8=вÕ@<hL:c§)zÛ•¶ ÷ãÞÞ꺰ˆ‹š¤Р΋|Åå¡2®QmšÚÆԨ䴰^ÿ¹S\ÕÀ†
+ÌÛêH¨QXΠ~à…ûàËdQQ¡8ºÅ\%~(ÿ¼þ
+MÛÁvPJʼn:e°à2w,œv À6f¢k¥1$€Þ¬ÿînP°Ì•`M;‡¼B3áà’¥{:ëí¶îéc /éQè0ò
+‚7áÀ£Ø_ñáÉ+®`'Á‡T.@CZÈ?È;¸‚äé(Šl=ÙòZäõÿ"[.ãü<ÙjJb’ I}‘*$áÿÚ‘Û~Põ††Éê\-c®ÃÇ™ÒR£¯#ùáj AÖAQ@¾`¶áM õ¦ß/&ýõÙyÊXU€„JðP™àÉ>€OúÉÜËØÛô¦Ñ2&‚ÈÜqê{b¡CÀ•E¢ÁÃGb€¹2J”Áúáé)
+bÉ¡AÖ3[ƒN ÙO+ytº’5ï.,£"ß·5l4w‚m–<ëøZv)Kb!f[bßî´*3Г)±¶Û-…þEËúàЂr°øQä]ãv³}¬”Á€˜ø@¡Ÿ¸´¶(ÓTA«Ãôx!pÑcXs£4ñ¦MÂ\Œ
+B¾˜†Ø™6£|8‘¡*ë9ÖÇ£$ô,|eˆWNé#
+endobj
+842 0 obj
+1691
+endobj
+843 0 obj<</Type/Page/Parent 635 0 R/Contents 844 0 R/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>>>>>>endobj
+844 0 obj<</Length 845 0 R/Filter/FlateDecode>>stream
+x…XMsÛ6½ûWìøäÎØ´%»²›ã439Øu+eÚ["A‰1H0
+ =/úâužý?Íy$ |pzö­*9°$¦òÜv7ÝtµÌ˜mú²öõU F$;KR3ÕÒ)·0Ó
+Ncã+—ŸA­Â†gt©C~Ùx/T™a*Êx¢çË3ƒ'ÕeÞZ½2;Vß; vjañÔXûÚµ
+Š†I
+qRm‹Îð܃¸£­ð€„Küöþ’]yÏ~UŸ¡C¼Bqy¹ø‰&M –+Ûëm¦-wl•„u7Š¼Ø¢™`ec¶1~ ˆÍÀÂO¹`¡x°1…|šcDv“£²krÞ¢èsÕŠá áÓ`—I63úµa#Ê~²€ÁÝ¢çïwÁ¹çè˜O!nð†ƒþï`p{í»É€eͳçùžyº±ñ¶¤•3ñ6øûÁ¦×˜c¾Œ…V;P!xn´.8óQÄÀu!ò!ÀHÛ…1RFå÷óG$Â8ˆ(éÁ{ÆE
+‘ùýÈ:Òx‘Ì&ðÀOzwÅ1 #Õ±_* øQùàZ–x”ù r|¿Ó§q­¢ÿћžacG2µUuVñ:o¤Á²îÅ#利yŸ"£€Td7 t‡,1X¿µÂÛ ë.ðàŽaË©æÏÓ¸<Æèï’ÊšÌn³ ~±¸ç—ÀùÃÓÇ´Ó~ãò~²9Þk’øã[ñðÅí?kïý¬qs{“ÝáלœÝóu,ŠßNþÕ骛endstream
+endobj
+845 0 obj
+1820
+endobj
+846 0 obj<</Type/Page/Parent 635 0 R/Contents 847 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F0 3 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 283 0 R>>endobj
+847 0 obj<</Length 848 0 R/Filter/FlateDecode>>stream
+xWÛrÛ6}÷W웕›–(Ù’ßêÄMⶹ4Q&}ÈL"! 6 (
+M•£\WÚ—ÆjÚ­UE¥ËëBþ¦p*—W5‘ªñ­L¦*ã,ek=²9+w_ÌïO†t>')8ŸkŸÐœ½ 'K•i*Õ¬«<7v“dõ®o8h¿58ºtž¾»0p±ÕÈD«°?#Uˆ¡Z­s$„Hºç;wÈ~åÏß_¼|Ö`£Ê¿wÑt\ü²ErÐ`@l s£…ž… À{tV{Sí/úvûñæÝSÄgŧ;@y]è­²5‰¯Q°\UÑ52v»gøo¢6ú¬QÌÆaD¡b™ÆÒùgéJ™"$̯óІ®Òq2¡ÉlŠÿ§øƒ(–‘e×4šD–]ή“«'<’ ~è Â:¼ñl»»¥ÄÉòäž2W_Á'p æ›(öJ.2ê^Kîµ…˜¹Ûz?—’˜Š)À†„\=8Y Ü)oQøœiº4¸ûmðéîöÛ‹HÃîpD¡0«uUì)7Ë¥ö¸Ç|úòþî/PÚdkZ+”ƒ¼²+MnÉÞÚ7Äâ2qðÂÆé^²  iC Jï÷Ýs×° 8<\Ž„„î*¦_SßÓ@÷nÁѽh…Š•ô¨DjòC\앤{p,¨„ˆ1îyn¬F~Û¥YÕ9
+ÉjÔ¨ebåà ì»çµEyg Xk^–°ÅœÅï½¼º™‹¢ è1chÜ%v,·ÐšMÄ’º¨B,0bO,°ÌP:§ ð5¡ÃÁv(6Œr¶'!6j¡‚¦µ.DÑUù‚Úÿ¥…´ àNÓ‘”ì²I´í$æ*<*foíÔ¾+=“ñ‚ósé__Ëd9Ž8‘žË„>IúôJekdÍuèÆFlnA&úöÀ¡¤ ¬´ÕJ‚à
+'”Ѐ“åþåZo@ʹÖyˆTªvÎ? /ð/¶Kèëlsµme TÞ%X
+˜£ðÀØ焱Êv?clý½ÖŽ¢äP¨…ˆhïÅž¥0w¥zÖ`Íp/Pk´þ—§ºjAá2¯«Ú[8dcŠ>Þ¾1@Hø µÜU…‹v¦ZãTQçM|ªŽ{³1 #œ ,Gí=ÜnóK…Ðó¤ŠN»M±ƒjin-e£¢öœ§E'+&¾ƒcb‹|4(Ã:|``-׃
+žItmF˜<Ãzt¤¡çšÁb~d®„Lâ Z¡,@,½ª5ÊÅnÃ@a m?8PS²`!Š”­ûr‚ ‘-ÓIœ‹—›)¬\ˆÁñº‡ÝŽ™Ý=ˆsÇs
+y?u{"Óø.ÍuȼY@7×ØëæJW‡–ã°ýÊÆΰùÚZÙ•q®ioèXMøº³”cgä!Ú£+$eïjO[?ÒÂ=âT´‡ÐÛ>?8 ÒçïÐõP¢—7XùçX3MQ¯ÿ Æh<}.חɈ©È!¢ ýXË«¡ƒ-c9—¡ƒleóê¢Þ3hÔ}¹Ç|ÈßâÁ0—¢ö·Åiß*ÇòÌ@‰2µQ <йÇ27€‹íâò jßSñµ"ûÁ­hs,؈µvµí~qd»Mæ ãÔëU](
+EœAù±$BºÀQ ¢`å…8U¬˜X5– ¾ Õ^jó;îò±.4´d‡— ÖØüŠN#Hçk¥ÉNeaØ0—·X« ífI̤ø8
+)ˆÕ éÁ•EÍõìËß(k/ PX:ÎMYÀ›88'/PZbåbcIˆäíz ¹q ºx=k^t£+.îÕô2™ñNÑøèÝ= Û+pŸOS¼”óÁÿ}ÁL¦˜—+ÓaÓ žü‘×ûŸendstream
+endobj
+848 0 obj
+1782
+endobj
+849 0 obj<</Type/Page/Parent 635 0 R/Contents 850 0 R/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>>>>/Annots 286 0 R>>endobj
+850 0 obj<</Length 851 0 R/Filter/FlateDecode>>stream
+x¥XMsÛ6¼ûW¼žªÌH´HË’==tœ4i3Çn¢Ž/¾€$$"æ‡JVõï» ”Ìƹt2±%xxûvü÷Y(sü eÉÅR’âìíúìüÃRÂPÖ>Z^­dÊ<˜Ïç²N&ÙAlVµy*¥©¤ÉŒýõÍúv%Ý®Ù*¸‚Ñu:yŒ–+ñ/ÝK¾›EË`Á÷kl•çÕÞ–¯7·ooD¥…)mjÕT5Ϩu~ªtKDµXY6&QÁ³B'™ÂêÂö+>¯ÏL}â¹s™…Aijî{'ÚÃ9#Rm$­
+eh®ˆum‘ÞŒ´¤¬$¯Ê­®¥Ô:¥W™zÖbõNÁOÍÃf'§©$©Ú²œò‘ÁÒ³®ƒ.%}–±­OÈCVõÙ5âV©)·.Çp0i þÿ’ýÇÝÃúNõT[³- sb¶ÑÅËÄ37r¨ZQµ1Å.×t€ùp~%“»èO‚÷aŠ*SÙ›1Y“25ʨ•5ùáñ –Þ2w¢ÿAµiv”óM]t ¯*ÜƇfvêS5ÉØ°‘¬3ÕˆU&¶ª`9?¯¯ïonìtÝLÅV.ÞB¼W# źi€
+Zy._~? £Ep-—sèY!áe„ßþ[._ÙÝs| Ø{:Uº¨JÄsŸƒFHóT¢KãÃQ§¦`øz\œ>ý^H^¾8öô;Þ^,ƒðd/¢÷Ç8ê­ôqŒ]lP.ŸÎ½Ží­çßÁ‚3 |*€¡cȃ›Ä’ä él¦®©7ˆ
+ní8øDñvuõlR@8>ø°ûx}×MÌ<Nvy»Ýº6M hÃ6ײX ØÌV7 FØ…2ñô² µg\rŠÀ}zQ‹<ÓƒV:³Ñy‚«J?bx©h„0‰tÜ•›¸VµAVU6££Ñcît?5
+§£"¸~Q6%nMN2s’À.óP„úwáùëEãmðر:í ¾g=waìk3ˆ¶3—aöÿqÆÅm w4$ íГá1iŠÅó·GLè䮞š _Å¡+ö*Ý )ƒ‡1”`œOZÿ>k¹
+¼Ìé„«Ä.òåþ–¬Dæy—„ŽlpAX¼Æ5nX›Ër,q8ÎÕ„¼ë®~äëSãªò 'óíèyy ¦ü^­.GG¨6þB€Ë»Ùf 0 ¦œa!ø¦v2SkÒ˜ÞYLÌ_„È(Ý%ÔÄZ…)?Õ;]º[p»Uí3 ì¸+7¼«õ³©ZK"t¨#¾º; èäÌaéüÃUÇ^áÒ$Ëë Þ<0ïëê.˜üUÛ…GÏf~ñl͹úµKÙbµèÿò±
+¹Eûóì__ÝAendstream
+endobj
+851 0 obj
+1989
+endobj
+852 0 obj<</Type/Page/Parent 635 0 R/Contents 853 0 R/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>>>>/Annots 299 0 R>>endobj
+853 0 obj<</Length 854 0 R/Filter/FlateDecode>>stream
+x¥WÛnÛF}÷W ‡(ˆEŠÔÕA[ ië"IÚZouQ¬È•Ä„äª\ÒŽ~|ÏÌrIÊ!`HíîÌ™9sÛÏ"šà_D˘¦ JŠ³7ë³_×g“`µ¢þQíð1¡8Æc¶ZâÅÓ`A•¦-öNh:›ãÓ-MVÓþÐb­rZp ª»T„—º õpP¿NeyBëdTS?{±þx^FnÄ΀|ŽTS›Ä”[·ÜŠËú8‚ ¼çÔùB}Ò”äZ•ß*¡*ˆd» QÉ^«˜ tR¸h<¾Íê=å&+Óo•È¦}ÏYÊJ[«<w2fELÏ Ïh/‚˜}»Þg–n³<?§Í¥z«š¼>÷Géêõ»7¯ñEˆ2
+[…¹ITZUlÔ±ŽQ@WZS½×T(vRR“4….kUg¦¤lKw¦ásGS‡æV•5Õæžzk
+}»×p¬Î­èm-ˆIåÖЦÉòTTµîNIÖIS«M®I•)åÙ¦RU¦m VH‚Lh¾š"º\ÐsûÈ//ZOaÏ|zÈQÌ@ èg‰æÚYµgF¥µà>Ù}P{y#AÃN|‰ŒÚ±ÿàð3süè~•Z§ÖªšRŒvç^½÷Á±¼¥Jp:ŽT¦ÙíÉÉ,oƒ,2‡Ì Ƭ¢CeºbI†˜sæÏž“5N ê‰DÖ
+Ö1 ”åÔvL¢€èÝÝ×#ÝfПó  d#QxÔ¶j6,u¼´mdÏ]PûwPH®ô•|±8.\]…e“Ú~á÷Û½JÍíp¿·ýÞFq™ÛG‡—ÞÝãhX7ÉKTPvg‹Ê'WWÎ/nu’E3¿#f% á[‚ÄGXÈS×P9ȤKÉR®½Em­³¾E\Uˆy[ëumƒPCºnššS…àö­ÂRE×#.„©)ŸsµµEŽ\¿hk4Vù`¡Ê†‘w4}YÖ‡=0ôÆÐø†þ£]¥ÞKÇæ r\:ç²½lÇÅâX
+Š/f: |åtÅchŸ5óXvΤÃ÷C!­÷Ú")`oªmReÉ*ŒüRƒDž;ºÌè‡MÁ€‰säɽ­®_0Ô~¼ñ[øw‡±á‘²Õ9×y¢O2©V·Êòïc± ›Q
+“fÛ¶Qfe’7©›túnãkoKà_»ÜlTþ7Ypëìè~óÅ”{åì‡ ~zláÄrüÔð#Ê tr¤s7(SH€zOÏ_>?we÷—ï^¿}ÿÒ/³@„}¼âKÁ$2£H¨•¯–ÌÞ¯Þ÷1ÈŸ¸šÓSêë^ ȸ١»$ôœüH/űñòž•Ï85YŠ…Vøã˜åe‹8od „5AÖ„ûÍŒäýöU„ÍÃ+Š‡ÕâäGA š±@9÷ð¥ãáŸ_€ƒ¿¼ŸÂ¿à»ÓCÇCów¡w“„.1¦# xJGUé\Ãï'Œ#ðSö:èBÇÆU”?N¡Ÿ®¤¯?ÄÏš%tExuÃȹÓGš1'3íÑ”é—Sšã弋枔“ªÃK¿L¼ª ®»|›Å]Ê]s~¯ÌG$:ý2¼îH¼D‹%¶—±Ü|ÛŽAkmyúA=ÄÓÒ‡Fzúl9CÙ”K™&çœýТe„endstream
+endobj
+854 0 obj
+1521
+endobj
+855 0 obj<</Type/Page/Parent 635 0 R/Contents 856 0 R/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>>>>/Annots 304 0 R>>endobj
+856 0 obj<</Length 857 0 R/Filter/FlateDecode>>stream
+x­VkoÛFüî_±MXA$JÔƒ’ …Û $NkA|9‘'‰6ÉcîŽRôÇwöŽ”dE6´q@ˆ¼ÇîÎÌÎÝ÷“zø iܧADq~ò~zr5=é“ íz—õûx 'c<à ZÒSñÖ‹¶#ÿÜŽDÑ0Ökƒ ò#‚eˆ¼} B÷ºGg4#›ѧ‰îÑ4nÿ{M‹t%i³´H¨2RØPdd–2Ëè[KÙ†
+)™P:'»”Z
+¬²2+¤%ÇÒ˜ooßN|™M!gòçÇ“>×£ O9…!'ïß2ºclv»H»?ÁŒ1æï'le^fÂJZª\&©æx»¥î–¶èWêòŒ.Š*l÷Íe÷Í}šO$!$Òcè"÷öb"
+-ï–±ÐK®ÒL.¤!äAB~‹ÀÇFÖŒlÔJÙ×~tÔMÝÊèn¦b‘uÈg¢Ë¼sgè2&‡^Ç8ì:÷ôBÀ¥ái
+J­J¥¥)UaÀ‹g¹¡Ë,U•%4“çôŠeædæj À££Ä¼úI™©¼ü¾ÄÔ:ÐœÍÁÏθǼ«=§ò!\,:¦óQ@wVhKUéJªÍ)¡DÈ\NVK©ýÅ×yLé+YØJdÙ¦Í
+ƒÃÁËÖ¢°Nç*Iç¯<“ÏÈp8D3±NK7ƒDeÑJ6©p¿´X©º5²9À]áT M%ö5Ä*¯–µiVqòÜ¥2&ež]®Iaè¡Â&³Ž…YÚ¦¨|žjc¢©ò)¡Ãøµ‘³3¤°å6†Z~ÛóhVô¹‡ñ?é½ÁåYFnNsÙZlPµÐ¢Piâ¨ÌRF¶6SÁTœŽ=׌Fà@WE¿
+‚ŸìÎÒPGHú‡Z– ¤É³iN—yÐdhŤŠ%“S‚Ÿ1æµëó°Q&'볬iiúyЃ¥ÿFÔë»ÿOÒØëûÏjú`ÎÞ¤Ý1ÌRo“ÕiW18Ü HLbrCÌX5ŒZ}€ã›sUøõÿÁ,ìl®¨S½ŒYmH2†óÎDüCÎà׬~­h²úZ{ýöë6YHû¥Ë¿NzÙ¦W/¶=®j`›¤qÇ­‚ëËN§Ï4MZ®nßýà¹|á"ÖŒÏ*àªÓl½7ò±øG¾?ØŽp:ØéQÏìâØ‚©¹á>Ä¡pÖ|
+d'tÆÏ—Öíl•ªÊ°kÝøK[kBù¦qöSTtêßüFÛã·ñ #¹ÃŽŸ“§ïN]í©î/øc,
+Dp"Â&!20¨³K¾#ÔÊ[h—Ü—Þ\«œÜ*híYöNÍÐ_G}ЃkhÒ:zx®kÉ-|“ú¨ qÛStæzGý¢ÕƒŒ-]ª¸Êáu®#xU'ŒÆ÷ÝìúESÊ¡Í‹…¡Ûʱ5!7q<àÕ8Çþ8ùçne endstream
+endobj
+857 0 obj
+1268
+endobj
+858 0 obj<</Type/Page/Parent 635 0 R/Contents 859 0 R/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>>>>>>endobj
+859 0 obj<</Length 860 0 R/Filter/FlateDecode>>stream
+x½VmoÛ6þî_qHÆÅbÉ’;)P ‰“Å–—-Ú†aÙY¢#6©T<cíß)ÙŽkeÃÞ@‰tGÞÝsÏsäc'€þ0 a8†¤èœFó¨3ðŽŽ`ýP÷ø2€0ÄÇèhBÏÀƒb0GW\?z¡µüe:<>FO·èøÈ9 FÁuzõÀþÅ
+®¢Žè_Œ Ë~
+endobj
+860 0 obj
+1172
+endobj
+861 0 obj<</Type/Page/Parent 635 0 R/Contents 862 0 R/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>>>>>>endobj
+862 0 obj<</Length 863 0 R/Filter/FlateDecode>>stream
+x­WkoÛ6ýž_q‘…Ø’åÄŠtmÐ`ëc­±aX†–èXµ$:¤Ïößw.IɲgºlŠ÷uôýIDCüG4Ñù„âüäõüäíüdÌf´è;|Òh\ÐÅlŠÑ-i‰­CšÎðxìE45&£Q0Û›ŒG{›)¶Þ‘Só@ìðzH/h¾Džä5Oìë!Íãù¿uše­b2ù"9›=Ò BØÜìùüvþëÕÏ—Ï^y/ã•:ò꧛o.O?¼}zdÛÒ  g§_VUY¦Å%j‹ïlIFê‡4–æ%³oò/þ+ÿÑwð[Z,Ò"9–ÄÿVÄÖÅyºçÇ ùƒž¹fÑ@ÞƒŸQ/Œ¾Y9÷+Òóç¤s,)|:ÌT¼Mµ0;‚Oõíô Z–•F]2ÿð÷ðú‚¢ˆ¹9ˆh€1ãn–´SmJ¡K*W’Üæ±ßÜ«iº·ïõ»{j*ì!Q$Ým¸[›)2W…!Á)¤†6*-ʾMͬT•%´$™¤RQ¬ŠBÆØ©8ߺÖsWùBXKMÁî\¤å2_`ékeJ^O]á[‰a„ˆŒ*°?`VW Ó1æÒ©E£"˜ûðú…G{.ÆcEÁ88¦ý¨ŠezWÁ¿'³äÓÕûÃn€3V­öÍX‰I¹H$¥Ž¥ÐŒu¡¶(0ÕHZ§®hP[¥×<Ò¥º“
+Yb`gúö¸X–›D°üîtm‡ÄʲV¹ê=¦ßÉo ¹Øað4ÓZÜl^8:t
+² Óºï²üwŠ”’o•ÙÖѱ°Ôtûùhqo¹»=C~B§AÄH›N¶J¹¥:(™RW1®K²ßœ;±@‡¸,[ #Ѫ&CôÇj±™Õ^C‡s'=†û°ž–êÚo«úÒµ·JZ{èÎŽïÖ%˜rh×æjéß5?LšÑkÌw³ðzæœh2–“Q0áýrõþõ}Òê+_»Þ¨¸ÊÑa+«wMúÁt„:IÏ߀hŽ;%_Eæ+< }¬ì!{_PøÁƧc¶Æ]ë—“mqü¶endstream
+endobj
+863 0 obj
+1385
+endobj
+864 0 obj<</Type/Page/Parent 635 0 R/Contents 865 0 R/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>>>>>>endobj
+865 0 obj<</Length 866 0 R/Filter/FlateDecode>>stream
+x­X]oÛ6}ϯ¸ÈIlg@Òv¬E·xØ´DIl$R%©¸ú÷;—”l×q´‹±)òÞ{Îý8Ì—“)Mð3¥ÅŒÎç”Ö'oV'¿­N&ÉrI»7[àÄΗü~±\à}:¹Jfd%åxxB—³e² Kç´˜ãÏ°‚ð Û7œ4¾½ é”V9 Ï— Zea}B«ttk,å¾!'í£J¥#ohcì5Ö4ÒVÝ)u¦¥ª*•3¤¥Ìø!©|)-Q)%)©G•µ¢¢LY™zcÎÊq8ž¢ÌÔBijaÄý²ú|2¡³é9‚Ye#QY)²椓ړѶ°?ÒžNHK¡ ¾-MÓz yY7•ðX3$¨ZÚ=º`_ÀñhÿÀrð&!Z•°L©Ð´–$…SU4<¼UºˆÎðÎñ-( Ž\½NR£óøõ€íˆŠÊ¬aaØŽââå°gç+Ç€6'ü¸ÌæÉã¯ú#¶fÇÒ§ãFÔI6cû)WÕ6ŠˆXçKU™ øÓk¨)xvà ˜ÕB4rªV•
+5ÏZB†ÀκõQÁlÍÅ‚¬í‰’-<[Kp߈XV?þ”'g¦\¶Ö^€–âëQiéYWq³ØwC<
+»x‡æßK¥§Ñ?_•ûN2$rß;òmÔ£ï#ÈqCVedr‚Z0]E™iו<ðš±n|Ô}Cr» l‚Â…žðhzv;hÖñíM¡{X¡ÎÓdþFâ‹„~‡Fñ‚“/ô]„¬šXÔŽþîEN Öé¶^#dx]ív²êQðÚÁ†‘ne͇ôOa
+ž<  îCü€6•ÖCwÃ`c0]a/!ÖûÐ<{çAõæ,{±|JyŸýÁ­·
+õÂ"ŒnéÝf7a¥aŸÃ®<*ïãƒî7ÊÃ9ú±j‹"
+endobj
+866 0 obj
+1577
+endobj
+867 0 obj<</Type/Page/Parent 635 0 R/Contents 868 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>>>endobj
+868 0 obj<</Length 869 0 R/Filter/FlateDecode>>stream
+xmRËnÛ0¼ë+æ˜
+~J4+ÜÕcvßfŸ¾~FY¡=òI½æB¡È‹¢@+oÊ2or<X#‡èµ5·í ÷W(˹¹j¸ÿ¦í “6ÏÚ(ø¿>и@è]Ï_Bô{¼”;1äÎZp˜týû!vx›È
+“u¿ó¤ïK›qh¨‹:¯Q­®Wü:ÂqÎx}ͬ¬›<åÏñþ—óa³½ß`ïì É€G+ãÈ!\¶’¦/gÔr†}x+ª¦Ê×|ƒ8˜¦¹*zÊÞ
+endobj
+869 0 obj
+399
+endobj
+870 0 obj<</Type/Page/Parent 635 0 R/Contents 871 0 R/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>>>>/Annots 313 0 R>>endobj
+871 0 obj<</Length 872 0 R/Filter/FlateDecode>>stream
+x¥W]oâF}ϯ¸â%‰6ÈJ«*‰’.ÚÍÇ.´ÛJ¼Œí¼±g¼3ã°¼ô·÷ܱ jSµM${¾îœ{î9—ïGêãw@㈆ç”GWó£›ùQ?˜LhÿaVxÀ´hD4šŒñÿhŒÈHZò
+ b›Ý¦‡·õi¾Äîçã ÍS?Ž7ÉÉõZ”NlÐÃ,¢ë<“Êч‡¯ó‡Óù·#^;Õk{C>ržž`ò  ÛËÏ–§ô©7Ä^Ík |ÐJ„¢)%Z-³U…ÐfaD_…)éZ+%GÚЋ·#–D³Ýà<à(O’:˜%¦ÎD‹ŸxÜ#Ò^qÀ÷üòóQtv èl‚Fã þÖO9Í•ðvDƒA}³ñð—Th„˜è¢Ì¥“$”Ý
+Ê”_ÌÔoòÙ"WU‰< é². Zs äFŠtK±”
+k}p2íR\¹:먭@ÁÎfØï: jóÄ‘5øw©BÀ¸ÃÁ¹™ÌQ€€‘šÛƒÑ†€v³A‡HÇ߸F›à;³úª3骲ƒÙy*Í!=/Ó´EñÍÌ¥¥Ò&&‹P{J‡'ê·
+Yˆ…‘ù¶Õ
+I:¼Jª“ª
+lqb!
+M®
+ÇP®¡? W ²Õ"ä5Q— ?+‰4%¨…—!9xa¤µxÒþ{˜Âú8K2ѹ÷k?eÖuºl¶”I¶ÄÖD_§÷³&>€VÈ/ña3]8|ö—Ûë!PE¦t®WÛÅ) Û¿ò$ÖU*ĶWM©Þ¨\ ÜCQU¦îÀµ²WN;†¬®|àäï
+–s•.¹¥X,
+ä]Å¡UfÌDÎÞ³G>ÁRXw蛳ŸÓ´»çxñ =Éc D¥÷åF§Eï2·º QÇnWÀ*É«e~õѼ6ýL,Áð_àW«Õ6 9pã ë©1ªaÐ4‰pK”ÃÅtôm5ÐdèØ÷ølî³—‡y“ð
+endobj
+872 0 obj
+1597
+endobj
+873 0 obj<</Type/Page/Parent 635 0 R/Contents 874 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F2 5 0 R/F4 7 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 316 0 R>>endobj
+874 0 obj<</Length 875 0 R/Filter/FlateDecode>>stream
+x­VaoÛ6ýî_qÈ'phKqì$H3$­³¦ÈÒ, ë0Ðm³£DU¤âùK{ßQrb;ë·!ˆ![äÝ»wïù­Ñ
+E o”ÚºÕXÑ´½¬į̀ÜõÈÕ( ½-+ÅÔêbAÆâ[*dÞŠc/»}U©Gdˆ)«äbª?ÜÖG[ýS‰þM—
+E·¡ÝÛ ɦqt|rŠæ OÆhUŒï‹úøxôZÔCA ì†Ê£ÈŒd•)ø}U+3ZWFs¨/ȼ‘®û™v¯uå|ÒJaðç–\i*A¡Þ?ÜÜ%ï>ÿ…²¤g‡p“by&A,ùΖkV›¯EĤºÆ„Xsg<ÄØ£—Y“Ë¿Cåµóä|+§JYzgƒ¿‚R
+dÌôÆ\¶Ò ]H9àM¬^°[a=$€Ðzûú•À6ˆYõXXskçU<‡1
+endobj
+875 0 obj
+1117
+endobj
+876 0 obj<</Type/Page/Parent 635 0 R/Contents 877 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 323 0 R>>endobj
+877 0 obj<</Length 878 0 R/Filter/FlateDecode>>stream
+xWQoÛ6~÷¯8ä¥)PË–íÄNž¶uK[ h·Æm0 /4EÙ¬%R#)kþ÷ûŽ’ÅéТhmYGÞÝwßwwýg”ÒRZÎh~M²ý¶Mînh6¥uŽ7×Ë­3š&Ó)~‘—¯w¢
+ÊQ:OèíLJõGúUJå=Ý‹r#ÈÛÚIEÒfêåúÛhJãÙç/ZÐë/÷üßžâG¾}<O“¿ÇuiBïLp6«eÐÖ´¦ JÓÎt¶dÃÖö”©ƒ*l¥2Ò†„!|5¤ÌA;kJeBBô{gâ<Õ^±úzùÚY; ú¢œ‡'m¶tôA•__R°]܈(Fv!wJîµ¹ÀYQxK{cxôDÒ–¥8fT3ÌÎc /<„Ó¶öÑûÆ ƒë<I¼Q$"tHðœ¹ÆšcÙ¬=v
+ÉúàZ„ƒ tÑBv
+³.£R…͸tšÐyLƒû…8ÍRt*ð×Ø@ßjðB
+Ϻè5ÆžQÛùl–Ì)½¹§xˆ\ã³}:q+½á‡ÜZ# Ί,W )øàèÅyE•Õ3€Øõn{µý +›¦Iäõ” d8‰PFOÏÄË$æÉVû30;9½xkF~«b„/ C³oG°ÍQ*‡†áÔ'bNo>|¦7¾çMm¤Û‰¾¾Ä6ðÁ¢„a×ö ÆÜõûQßð»1@['ª–@ûtËLªhP±rŠ+öh´”Ë–.ÄÛRÅÖ%ÈT"4¹…‹ÎÒäÕòå=[âQ3½ÃHŒ(¢V Á“-w¶¤nj?Źoi`BÜöPë- ŽkQp§}†+ÎëÇš[î×q´U¾t‡qÉ#‰Ô¿¢¬àU·;‡÷Ø?˜9€õ×°ä|i’¶:2Ç#ùã°r+é.Wdaà†¯›½fvc‘|Ü
+[1øzƒVêXÇóâI •É@ÝÔ&#Êh‚•z܃ò›ÆŠS^¥úhºÞp^NÁæˆ}’·:Þ1NfœTÔzlV„Ž+Ü1‰]zŒ%Û9Öèö§EâSÝNˆ®äOíÑV™“»«nÏæ“}ÀìlœÑmÕ. ·xþå´.Ýr»w­sNÇ^8¹[u·Œ9ïù­1ýüÿbëȺX.p<&µšrŒè;þ3ìendstream
+endobj
+878 0 obj
+1481
+endobj
+879 0 obj<</Type/Page/Parent 635 0 R/Contents 880 0 R/Resources<</ProcSet[/PDF/Text]/Font<</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>>>>/Annots 326 0 R>>endobj
+880 0 obj<</Length 881 0 R/Filter/FlateDecode>>stream
+xTMo›@½ûW<åD¤‚›øTç«í¡’›Xí%R´†“
+‚´•05“K±4(ýr‹Ní¨8uâ]ã|y*—Ó›œŽ<Q@ËJêŠDÅKGm©v¢#,áÚŽ‹»¡ rSI–­í6| Ui—ȘD´gy$ïL¨‰¤“£wÒž˜T—¼æL¹îPÍVìLt5ÉÀ‘‹–ŸÊQˆº#NïËs# þÿFô%žfßof/ñKü/W™ÒŒ)#í¨m˜é¶@Ã%éS9ézóY¿e+Ö–ÔîŽ(Zî@!EC.×+÷ù™ˆNì½í§û9Üy69WÀŒâè:Cºunf‡&ÒŸðûÅ€v’QJ1I:¡û˜.ÉQ¸]sˆ6LA“ž„QÎaÙ|ksþû€B«ŠÖ"ó÷øeÅ&ïhbÆ©A”Žƒ¨ªñäÀǽ“C:HìÔÀç²jöhhpKC-©ß\~rËÉd9ä“%<ܰ쭔ƸV·}„ £ˆáCºÛP㉩&¹²Œ<ÛnÌ¥x¥}B³ÎL.Ó•³±ÙpÛ}·§PÑ©ÛiÔëðcðs¶©Ëendstream
+endobj
+881 0 obj
+734
+endobj
+882 0 obj<</Type/Page/Parent 635 0 R/Contents 883 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 372 0 R>>endobj
+883 0 obj<</Length 884 0 R/Filter/FlateDecode>>stream
+xÍœ[s¹…ßý+æ-›ª„æp8¼ä%åK6ë*_6+m9¯45²ó¢”7ûïsh
+u„ËátÎí`2ý¨s•ˆââÉ«§O¤»¬Kzù»Ñü¯UËéfb•]?ZÀ*û^Z?\¨U>þ~ª6ˆ1Cá…1ÃvDVTÄÉŠ˜¤lO¸8·©£¥h] ±b&èmOÿ)éI‚>l§þaô¾ü4¬Š
+Œn<šÚJ$¬‡œo†T Vá¯Á’
+xÆnµÏ RGw“°žq»z?4™>¤9‹µ†…ñ<ˆ.Ô°Äœ&n²WkG“│9©>v=ë£9U„Úœ”ûž ʬêàÌIõÒgèF(ÒžÞm¶W›ýûÜ•¤DWNg☓ÐÄ&E*0 ZÃОñt³_7Ñ"`‚Ó‡s0É"¬=Œ—¨Cr4á‚ì¡•Ñfí¡sö úØw¬öPj{PBì<&DfE˜8{P};^È$Àˆ¬
+ŒÙBLÁ0"¶blv·‡ãyµ§ «hŨzÿ@€7³Šs‚Ç–É£¡ö6_©9kê—3¸Eµ¦xQ¬©_ŠÏ´Ö4µÖ”ô¡ç>XSM¨¬)Bׂ2}:kMIßNÆð
+ HxvVç2Õ]ˆù¹·”öö-¤£—øÏÔ$a=ã´{—}©û´ËŠ¡<c}Ø_oÞßWçÍ!O~¬­›ÃÄMRO»Þl‡Q°Íùמü&?õÁ!'C dˆ ïÔzg†ªŽ&Ãêh†N_¡ê£Å°^‰öïO ªºÅ@Gdz\VnB^Òˆùub~LHP‹øõp—W.,b6•q`Jµˆh7ÙüHÈ¢…'³-`!b.A"‰Þ§bs¦ZÀ"~Ùœo‚E@L§¾(
+pq^Ï›‘†ƒE †
+€é •5’P,©b0ZÀƒ®‡]òB,G&1ž…(×C6ûá|5Ç*¶
+xÄꔬ“E@LZ¯Ü6©@…ÈÒ€†‡%hO¸Z »Ã>L³²3ôuV.Ö’±ò/ë“pA–Üa·Ãø$D-Ù†âªú8²^o{Û1‰0d3­g‚Þö„Y6<’ÀîÆsqÍ Ðûpyü5õ‹€@¾fD*àÛÍÉLÒ¤”ñB3ÃўÓ4©ÀXˆغôWU—œnVÇ!/ËÄxgâŸME”ë+²ú¸ÚlÃ9::Ö‚4•CJ<‰I$ž ŽŠ+“¨ÁÑ7Ë
+Ø*¬·Ç ³þbj"—pamv,õK6.Èf±®´µÄ9 ³ZÕGc}´ÚŠPÛ­¢™1A™¾ g¹ªW+c€"= ¶Ý„ˆöňDõŒOZoB-äT¯7(¥{” ‡I&ööÙ D xÈ*™kÄ~Ã4f
+õ„ço.þ ,¤ïdþaH*à!o¯ß¾/Ò‚Þp-’Àe³_þ«`H¸kºIõD‰|æõeÆ°˜™œ$šgJ<¦y»ÙO>)ÁY†°’Ûh€=åÍÅãIaJN×ÃúÙ0´€§ ç5Æpê&ƒE|cR1ÎæÞéÐ8‰)L&¬xÅ#Ç‹â$¦K¬i\dˆ¶TÇYÑ °›£† ·=âíÍ*Çñ$Ú5ðÎSKÐÛžðâ:Õ€$Ræ ÷=àò;/%˜"(Xæ¸j$°Ç<?ì—…u  êž¢`Oy{8~øs˜dì+Nõt1õäLá•åL <ã&^-Ì%ºâ ¹ã$²XCQáùÃÑaÌ–`zÆóÍêýþp2ar•ª"Û°®. íQ?ÈÙ…#ç©dÏ<Pþ‚kVÛ¢¨¾¬»b‹† jQdaøuZ”¶B‹*b¹ÀPœ2B´B\¬·y+™4謒ѰLÐû¾/ž‡FDù{ý‡{à‡º´ Û#—)7l¸ †íïiÖr~;CmÛ!$›2AÚ՞ݬ‘’
+- ÒZFÂÚŠp,J°ê ZÀ`äçÃú°M…À,¥+Íäórø8l5 =ìP±ÝÖËi|„ êFBøã£ÆŽT„DsxvfHGVŒ›½Y™Nº²•iŒ) ì+cb;’2o!ZÀC~~ýâï¹/I&&!k ÑRRØXDñæa”ê%Æ$Ę²od ZÀž…ENz²c &𘟉YâÄà!¦Â™™ýpè"¡àuÃÙâDòðªÙ¯œŸF[TD‹”;D"Ì[¬/ë˜ú¤!+ë[ÍY÷ºpÛ8mK¡A¸ ÆAwÝ”SºØ8Šhñ/¬’Ò8ãÕêö–ã’É“å“$®¯ËÏØ Ú¯v1óhº€ì›5óœí­Ãì›cƒxQš´[Êá]eoe[64iB ûdåŠð­o0ÿäãnÒ 9ÃúÂô¾¯Ò}«5%ü²4öËÌV%ð¤‹!f(c…ô ÃŒÔ%’ÝÍå@S¢ã…6''@wp¡vZº/:±Bʲa…èRÂ>’ Aql†¾ 5ÓÊè}_‹Hú~Ä™ %ü‘(즇TT¢{Ö«‹äÈYÄ\–›¦6(€_x
+xÈÅj÷n¼µ¬|¿°Yç€ ¥œ®Ú…‹lŠ”ÝáE
+Üó8%î#…Œó^F¨Ñk_…Û»cn–a`aãŸC¹ò36Ù¿ÜìïÊV;‰‚­ºÆýžç³ØÆ Ù×üÂ#4Ù¤µÀNί5e¤ dH³Ó¸X`¡! ŠÐèˆÛÆ ô¾‡<Æ^áã›Ã)N ˜P¾Ú£¦GþmÿÚÂ9KXªKNM.¨ä…&z›Hš§ Ñøøª—¥L˜ñ¾C„ÆÁYéaû1ç`Ûö+ÙÂoj˜¥qñèn‰6âC„ j—±BÚ…ö0Bc*¡Åò
+†Ã…zH6œÜ2Ø”üâ3Ùoj*lšGŽ€s*V¼(Í3A†ˆŸ÷÷gß?ZœÓM‘ò,9w½ï!¡yö§‚…õMn¢ùüO;f»™ÌéÍ…xA ƒÕ¹ŸòŠÕ„?éÃìdôñvE¨¦¼D9Fü$õÑ*Dh…ÃÑMyE+Sžlvà8WòOSòwX
+Te6ˆ­„vŒã<„ìÂ3QAlc’ Ï/ÌåVjηf
+9Ì­É™”Ä·€„ j[¸€À-9;W’º¤çâŠñüu¶Rh³( yÆ+­ƒÞ÷µxy8|¸ /Åuÿ'‹wר88 GÌ¿NÂ5j8qô΃öØ‹Ùr:iÑž+ÆÛ¥UIkÅ~œ/WBïû„]jUÙ]þv£?›kk’8&cJïÔª¢~ Z 5Æ|ª‘œÑëmOào.Hô—*W"† LOxwÄö oU†5Læ`R…# ÕÒ'Ihº¾Û#Óð°Ï[„-ie† Á˜!iO2/°¢1Â7†b=ã¦|Œ‚UJ¾‚a¤žQŽóX©]5R¸n·‡œþÌB`Ð#{ü4©€Ç s_>)¢«ƒã_%{ 5,«žbîFÀdª¢XÏhðH²/Iõaµdk…h€Y©€gyÛc)vÿql‡èЀ”íAwlÁ¬%¤y
+
+
+r¼(ƒ¼]ø™¾¸Í0†“z.éF­·­¾,LH ¼œF¹Þ·r·(a ˆp±‡' nåZÊiXß7çlÇ,Éiø,Á(Ùb·Ö?NÆ¥¸NKÑ–ÂFL°
+vMš –À¾4 „
+S൘ $
+XN¬69–‚ðÏU&°ëC>Œd XœºM,á4 »ípÊ®Ÿ…2e~7Íš
+X BâÉY|)»ÞŸÚ.lMöJ ÛÏÑw¼ N´l0ƒý]!&BX·Bfâq3p˜Z4 áeACÐû>?´ŒlÖ€€S4zx¤4*ñ®`]?¶I
+ÒË:GѾ"¯/Ó“°œÇÉß•¶MQªGÐn‰€Àa<ŒAh
+±Ïµ †ü·Gh
+q‡suä­í§ #TòŠLÒ_ð8zŸE>ÐòƒÍÖ¤tH
+E^ßÄ ²ÞjÄ–‡¬L¿ŽOøK<[À)!ZoÅxµúÍ—Dè°0ç„Þ÷Ù²Æñ° p@` (€ŠyF9ô"…žl–Y½ð„Ý°{WR)X(Æ'¹Ú£dÁ·Ú4¶bÈãƒæM<‚>ÔD"\ا°-à¯ò¢“E2äàÆ Rp>•à`è¹vE€=¥x–`>À³øŠ(Ó#|ÈÀR€¦B™'B{jruØ­6ñ My×㿃n¬áçeo.h¬!)Éî5ÉXsû4QÓ@ì¶cDlä™~Ð$8–„6Æ TÀWÇŽ9Ò‚èÑS´€§³&øp¦iS-P!Š³&, Ǭs‡Ðâ~gM
+ßÇ“D
+›¨úŒJtÏúñÉ«<³
+ œ÷b¤†ð
+ÏY…áR5-C±žq…÷§›wwçräÆj¹r hX©€g’ž‰U` ©.?
+àž°F”vÄÌò‚’•˜B–²å(Ú“| Ÿ7Ìçˆ,± f®P*àA+ãŽd€…Ó£Ïð#­9-ÇÆeN ?gÃGE—[‘…ùßîYó[þŠÁšz)¬y¿:Þôr3/xÙ:g@¼ë´¦& ôHþ™½Þö
+»L§ß]È̼"ù||¤y~XßíñG: ošôÍç!_ô»ü
+_ÇÿÛ£Ç)endstream
+endobj
+884 0 obj
+5352
+endobj
+885 0 obj<</Type/Page/Parent 635 0 R/Contents 886 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 417 0 R>>endobj
+886 0 obj<</Length 887 0 R/Filter/FlateDecode>>stream
+xÍœoo[DZÆßûSE‘¾Ãsÿ¸(;¾u;n¬Þ\à¢(h‰–ØŠ¤JR±óíûÌììî3s”4v,å&@¢£Ýç§åîììììþëQÛŒñoÛÌ»¦Ÿ5çÛG_ž=úâÙ²éÆÍÙÛ¦.Gm3›Oš³‹f<ñÛóÏÎVo®×Íþmód¿;­w§ãïÏþñ諳GRAk5­üôí?êg£q3›,ñßm3ëGS{¸n^Ë
+‚ÃeóųIÓ¶ò§ÑšÙŽþîdÔâßÆþá¶Íb9ê<;ÂËýi­­í&£>÷ÙÅg£ÿGÿt}íÉfÖu£ºmÒŽ–ö`Ýöų©u:·ëQ‹{éÉÕêæ´>än"ù¶™v‘eÅ2-ÝLts?šû¶XqÔÿõåóÿÍ- ѶiûÅhâV¯Ö‡íæxÜìwÄZ`›°'í%ë˜\!¢¾ÜœŽB2@°Á
+²Ú]©¶M×Íb¯
+Œ¾+)¯3V!BÞn™b 0íŒÌãFH4–ʤßéº$Wˆ Z8IIJ| ««òiHƒ)†¥ma"áõjû¦PX'®c×á>J®)Ç«Õa-Û!üùVý¡]˜è [“ÉêM‚E\5ú0L­Þ}Êjãyý]kFRa¼ZqFŽaTÏpÖG4Œw„ õˆý»Ýúp¼ÚÜH_«ùÙäûú?Uc¡Ó'…>ÐXÌǘ[Þ!MÂh˜>õëÓh wŽ‡A¬ë˜’¸Ê#’úIfv
+²]ÿ™»”EØña&E„Q=¢¹YVÛ59-*âi~Érl»àE‰€õlu,›$ï¹æÁZMoÅ€d­ÄÛkF%ÓcT¦ÇæÜa±’ÌËAÄbÍÚl&$ËrƒÆfüˆÕÈÌËŒAwÙm¦Àmb‡À” ŽöèÉÄn%aá!V!BV§Óaóæ–f
+F’1™9%kÎ`Sß\!®W‡Ë²Ia(šìs'Wˆ”ÝíöM½NÀB`²ö#G ®‹ØÈ°ÖÔN»z„Q#B=O¶¦Éîô[S¿”d~;=Tkê—r%ZSÍC«µd‚Öu+ŽŒÇ4I†¾×M¢ƒXy„¼¤£-syã™y&—A$)@8¢\Uˆ ï7Õ°IÆR„oŒUˆ Þ—‘
+Æ„ulV!2âe R‚3•ì–k ÐøE¤ÔÓ_–
+.|=Ȳ\¢½áaXÐ-GZ½>аLfƒøÑzÉa¦~7BÚ9„•GÈÝ;­¤D×"s_ÆMÉèŠþ‹”àÌ2DŽc"'í,Š$!Ö)¤`+c"æÕêüŸ«Ët}{Ô‡Ê;„ÕK39ÓPÝ3EïWý_0#è1mÏ+– 3Èÿ‘#€1¬<ò)C@Jp¦2k'£#è¸>`¨Ñ‚Øõ§Œ†3é'F¥¥Þ½>ШÈUrºÅ-¾/†Å¦OýÇú4&0“·½ì?ÝßOÄ ¾CRþúZ3EeLH+³KŽHÉàõäzƒ ð:"rüôëŒHïn¾öȦ–S›ô@ƒ1÷㇣FŠ
+à¾j‰Õfâë ®¯ 6•œþ ÞovœÐ©:±)Éì9Šqc;Võ8Ž4 `ŠaàvdhDÔÄ‹Ä ä/0jD<õvIB1*I¼zŒUˆwNO2XR±-V!Bœm²N<¥rº¦ä
+‘O)K9lóþý¤·È)Ý5îôÁìGeH¹­VhjLI|PV'# z×W¤ ”›•Ž`徜›!‰XO+&ÌMÈLOÙ7Ö‚»[˜<Žb`OÛ÷J"1yóÐ#¬‚G$#Ö65’àéçbdx_Rñ»^îÐZ>'=ÐÐ×ûpmNitM¯K­Ó§âừr ˜4ú
+%†NiÖ€T<
+DnkÐœÏ,üÉ"Y´íª¾ùÀJp°ëŠCGŽvX(ïúÉý;ÿŒ1öÆìuJãàÍøË£õîJ’„ßåJRz(sZì@|@ ]gŽº;#µxµ®]Ÿ •–“âÕa}XÿëvsÜÔ뀬†ÕáàŽ”Y¹BlÏ·ë•œwŠáÁå=Èjœ·ƒÿû.–íL¹Ì”¬_¡áúƒ‹Ð°5÷ÝšÕrÓ ß¶ ,îÖø¹ÖËÃþvw!]§õqV2øLŸä¡cp³³Ä/­>PÇÌã…Od­Cט¾EÔ½€Ÿšëš"»JÚG±§—„*WˆÍá“dRëcsß¹ÕÞZãÝ-©ÄÝÊ!°o‡UˆíðÞ……pRð.mÀ9b‚w‘ùÞR’wïJúKî]©—Hdúgq¯3˜éõM:§7¢¬\LˆÇ,$DÏ#³‡.S¦5ÃÊ#æÅêüj³£U·
+Åäz«Ãdräœnå8Žu²bJÒS )øZLúúe,_4ïÁŸ*Wˆ Ú¡±
+ E<Ø`„B¦‚u  7CÇä
+±%)C^#RbáÄî1tMFGN°X”Þ•ö‹ùe‹3ê
+‘’ç¯Ú‡$ÒîÁûÂ+åNš¼”W2— ˆŠjÏ›ŒÄ-ö‹ð Œ°òùÍ7»Ï±p~þìú‡ßäøœÕâ8%©áX¹B„ Œ‰¤
+DÆD" N[1¹ùsejDcb%8˜˜dÌAü"R¼)‘
+ $t1ÇÃ*D
+›æק3¥‰»ÓØâʽ°ô@>¨ZO ß’u˜ ìMœ
+„°ª
+c­7ÃÃÊ}+8f#
+ëL…]Æz+Ž„'ûí¶.<$“Ñ—¯Ép%æë ¯{|}ݶD$¬¨äsÙGÉb[(ÆbÈñ`t ÃFÆW‡Ã>½»‰Wî1X¿c$G~(‘¯(ñ»þ\!›½1×Ë¢eb=®bq*Œò×?OërL_Eè9݃1!•F«ýõæ|³®cXubrŠÁÙ¹ >_UÈèIÎÝÉSñ ‡½¼M™Î$æy˜X‡r’ÏÚõ AOÆl¦?×\Ä›ôx Á ‰ñ¿EÃbÀœ¯V º&ß9}*~^¿Õ¤Š’,Á˜qµ¾¾)£o¢4úŠ#áœÿà
+À¹S#àyùûU¿+µ3/OÅQ~¹>išï·=¼éÀˆ&î—þJQ®ÖƒxË/<pbÞzLŒÐßS& «õ ä>×QE2ú62!•ÆXš£ô•Éø‹#e†Q#Ľ(U4
+d<ÐØ’¯÷—û]rüâ1ïaà&.Ác/ ³´oõç:T¸ªƒ,N?W‰L/Is°>•FÂO —5¤Õ^e’ × )?1`JiJèئð’%é0d¸÷‹¥¬_¬8BnË’Aèq3@^©#}"Fý·ûÕ–²Î¤“T–~å
+endobj
+887 0 obj
+5223
+endobj
+888 0 obj<</Type/Page/Parent 635 0 R/Contents 889 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 463 0 R>>endobj
+889 0 obj<</Length 890 0 R/Filter/FlateDecode>>stream
+xÍœ_s[·Åßý)øVg¦•yyy/ɧŽ"Ç­g’ص”qòBS×[þQHªN¿}Ï àìBnãid»™éè8?‚‹ÅXàò—'ÍhŒÿšÑl2jûÑjûäÛ«'Ï^,F“ñèêý¨égͨŸMGW×£ñÙxŒ]=½Z¾Û £ýûÑÅ~wv§ã7WÿxòÝÕ©jùëÍ_ä_Fýtÿߎ¦ÍÙB6£KùWÿp3zö¢5|2t>Œ>õâvyw#ý0ÂmGÝijc±C,Î’šÛÑlvÖÛ–Åb§þëþC’“b;š/Î:+ÅN~Ú'5 ¶£f<?›[y,wòóÕ)éYÀ¤9k-@+8Âò˜$@õ”éE_Ð÷ó³©k@D:ý·ËÕ?ïï2„d[ø[ ‰äù~»\ï„e€ôcß“ZÁAÄqûͦ¸KšM|Ÿj¢–€ùØ÷ª2`™¿ )¶£¶™žÍ¬Méô¯ïÃæß Â2@0òÜÓ
+r¹Ü¾Ë aFí¸õÞ¥#›ô:5†¥
+;XFyÛ£ùžžÑÿº™F
+j_&1íe,D f8ÝæhÀ™fÞ°Z¡bì†Ó‡ýáŸÿGà”Uš ƒÖ)û“ußn!_j‹p‡Šûv ‰^vl·6I„U,¢ A‹=ƒ–Q¤ÓÀ® Zî ×{r]R cŽ›V$¬‡×% ³>çê oÑAÇÓò´.Ãj°27Y–â=ëýz—çM–Ái°0Z8ˆr=d}Ê#šU⺲š0 I<ãÚ.¯HÌbâm“È³Ê ¬èÂâø¿“ wsžÿ»yvÑÙÂ9𼎾er"Év„¯çc½[ÂÛÛ!‡’ ¯Ç2I€–[À:w+¢çÂW¸©‚PtoO¦² ²­` ¯Ÿ_äÕ
+i@˜Ém ZÁvÃp=\‡žmeyø;õì'1ëývÐJÈf²·Aljçà(Á>°“QÂú0wáb™€4ⲉ1„X^ÌŠ›e€`sWäfh…Šò.O4,a©¢„AÒ€ÐËÔ6"V¨~WW„¼ZoR%W»`!0]+ŽÎ&Ñ
+¦,bà‘꣸§ C]_ÖÈ]x ìdn´.Ø9T=F ˆõÑ+Í¢¤AÃmZì›pÓ$^ f Å^ÿ2ÅRÀo°oõúHôúã—±,ç•Å£iBªà”L ؼ!²Õ#Šÿ“Fü.áÜ´‚'Ø¡L:P°ºr½‘Àžòíó‹à°“÷¼¿=2~bMçÅÓ6lfâÔÈ‹±°Ó
+DÅOX®ÅV~yÚÃIRÁÚª Zî’‹ûCY%’LæSYh‹$®¥ütÏ~X®n×»¼F`1P!-oP©‚E¯VÈÄä`Í:¤±âIý¥†E´Ð2Ö»÷ûÃÖl•X)ùNIUšÖ Âœd[@ÞNeÎàJlCÊÂ%
+žÄƒe€ÌÚ
+¢\¹ÿáÌù½þ1'µ9wßð¸žb9¸à|áº1›ƒÃh.û×hr,dáiÆ_+ÄåêvØæ•/É`ÈC DË};–”±"‘ô…¤Ð Tüƒ'¼6aJ8ޮ˩ ‰šË¶Ê¢´‚‡•ãUÉ”9‘1ÍfM*%nIVåSËHXÏxó"'WXF×H4áv¤
+ždõ,Í1,“iRæ Q®‡ \¯Õ¹;Ä$™`ÿß°s\|´œìG' ä¸]å¶eÏKŠèrðÖk¹%`kÿ~}sÏ+,ñÖ$¨“Å£¥
+–d·l¤ç•§eà€rê¾Í‡õé6uKÄßÄ( LÛ fÒ1ع>êÊÚ¡~b"6aE!y¿ix ÄʳZG˜ _QÁnYF¿À³g¼ºv&Œ“ä?1Þ¹% ìAÈ0o$8øì±R=Æ‚æÁ™ß%¬<‚a™sÒ¡ÐÍ­´yÃì:A jwú”b9ÌY1$•1QÛ·'ŒŠÏî‘ÆžòзÆEɤȦ‡Õz¥/ ªšq'öeBŒ2CƒfÙ‚‘R]Rš†tXýÛ¦ðüHéñeKÐ
+þëü‡àw¥!$D ÁòÔ}¡Dö˜ír·¼¶¸ªŠlfÿß™ ê¶úlG¶XFäUN|(Ù"‰h£#V93Û‘ ÐŒe½h¡#kÆå°ÂlqÊ·cX‰n‡#†“*øÆpW’
+Œ¹,Ý,C+xÆQöõ4÷Ÿ}ÕOy`µsqXñúc^…ª¹ë •ã )Nɨk€C>Id8ÉÙh¹mÁñnX­—›2H
+–ÿ¥$°Å,O§ÃúÝý‰I**MsÛ‚ÏÈó?id'ó¹%hK`‡»‘þ±R¿®ãgrÕ$u|x ŽÇR¥šô˵É8ÐÏ'[&h¹g|÷ër{‡+£ê,ÌÀ˜TÁs¾þòE†DHmAzV7­à!ßa³Îw_H)Ž„:Ž£<‡=€TâCÒ‘¶-ZÁ3òŒ5âC²µ…z{‘˜}¬-mß™ø?‹I!µáÜ÷†­·Kª$WáêI{5­Ø‹Zî!û­Lba´à6ÎüsÌbõ¼öÀ¿ô½šF6 m+1Q/<ǵ g¯[œœÛ)ï¡üubÁ8S++ä¯kÖ7i„F3ئ1Zì[ñÓN®†å\MÈQ§V4øfè©ðý´Zî)ßïoö»¬I'c,LšLI`y‡kPC¹qÁJŒ’ÉØ·&U𜷸^³ÿÛÃJpZYy›o•*xÎWɸ,’+ç¶ÑŠ¥<€V¬YK y6Jªà?ýøòï¹$“ô€YˆVðû#T°|ÄRnJªà)°ë;˜VœFüäÀÓ›«¼’±/+’ðÇ å·[y5Þ €ÇŸ‚°âD¿2(;Àù»ãé°\…µq¸õûÖÆÄý“36#eöj$d·Û±¿U ãÐ3¬Ì³Û-¢u*Æ×Ý6.$7Ôrî?>ëLp“ÁMJxs"‡Ëðí
+šlŠ
+ÛP¹f?a„ Œ
+!×—R(! ú
+®†¢÷ e*-óŒ—Ï3€$èþpÂlZÁ#Î7›}ô$ñK\ÃüäÖÇç°ÿQ237&!õžVs៬9èÐ78‚"þÑñŒG¨o†ãý&Oq$B LÀ—¡å¾á\zµò .ÔØÖ¨ ¶yÛŠQ›y5éAeJJrÉ¢áEþ
+2|Õ,å® D Ì C6œ ©ãûõv}ŠwÙÂýhoYgümO³t8ÖÕ’)ÓMx ëL*Û¸Sø$—×jឬÓ# Ư6H6Ç‹±¸sþ5 bµÛ,ååÔfïî„c•ð·Z…ÏlpØaÝCG6
+
+Ç+ ŠdOÀí“4 Þ¦–ßtau,ôêW—“¤.
+q\9&dy,õò‹Í»”D •„
+N/ƒå3NÞÖùg&9†¯›/ …¿sgÒAÂÜ_“Õ(%#‹+å„¥ s‚«Wúç‹É Y*|1KX»Ð“5^T ARæ ðw‰HÖº0 †!Ód 6tò¾!ë1iUzÊ–ú1¾â¤!úá±Ôüª¼µwjÚv¹Ü‰_ !½{@y¿«(ðñ}øÕ #@/OW Kž¥(wà§;‹=æÕå³<ZI„­`¸Ée‘é o—‡|QšD `ÂÆO0QP\÷‚ñ/Ÿ¤O* Æov0"B}#ÊÅ’@Xd}$zýˆí@*<b6±ý©ÅÁv ‘Â/Q#´Ø¦É¤€1Úv¥{yù)-’ˆ^ò¥l-®ôùã‹ò™¤–¬<
+Èñs@®íhå&°dK¸Pb>=­Ü„•‡6¨„˜­9Éðw *Èôºœ,dÜ\õs™4X°RéÏË W©/ ɽ±8–úÇ¡@„Ac‚¤ÜªÏ_îÊe梀¿a @ß‚½4!õ.©d#?§gZÐáž»¬Ç{º<[D¢ÚxyC|L»
+™0ý çðWøIfœ1…ŸdþSƒ×<°·@‡ÈïÓËó¾=áêÇ?dOù|¿º—ËÙù0GÞUíGš…Û–O×뵪ÿíÉ
+endstream
+endobj
+890 0 obj
+5146
+endobj
+891 0 obj<</Type/Page/Parent 635 0 R/Contents 892 0 R/Resources<</ProcSet[/PDF/Text]/Font<</F4 7 0 R/F5 8 0 R/F8 10 0 R/F9 11 0 R>>>>/Annots 470 0 R>>endobj
+892 0 obj<</Length 893 0 R/Filter/FlateDecode>>stream
+xÅ–MsÓ0†ïþ{,}Xþ8¦@LxÊ9±Ý’Nƒã~>»¶ì¬e†Ói“™Ä²´¤}wWú(øUk0äUp‹u
+ZBvʦBA‡ …”ø6¿Ê¶»§ê{XÕ‡¶<´Ç7Ùcð> h@7
+=}ý@o
+Sü­ T"u'ØÐ<Þøæk JÑÌhgq26ëêûöG[6à&c¸
+l"Â)»ïöʈÁœYT ¤¥mv ukëû=û·ß²ÛÀah—„à1–y^#„™!$…ö æ!6Ûj· ̦BÙba=B?ÀcëS“—„›!Ä(M!n€Éëâ‚`FˆgŠ8ª‡8ïÇp$ÄÒ×Ô ð«» …„VÂ`ÔdÅ•x¶O"]°™ˆÄ5V$È‘Ä¿¾á‚e±]ØbE88™D.†Y£àª ¼ìX®ßgÜÚ¦.Ny»¯´(«1Ržy»ÿí7ÏOZcø ~ênoäm°“ç5zG{Þq€$¤ŠÁ½sf !’™ ¹7!©8Áõû‹ð²’ÙQjKªœ2€}L[ëàF”Ø–2j‚pTq¤äuó@*‡sàåUöô”)®õì*\×`z*JÓ™ž,Þ/Vè©IRΈ°=cxr0+µ;“8ÃagV\¸2°¼c`L=vÆÀØúUîH ãÚ_^Œ>+§’Ø4Âôw’ô‹$6±s& K2’d@ô¾›0P’9ão’ŒŒÎwÆ€õ—2“ddƒ’Lë3òswã ÂñjzŒµr†î:61ø‹‡—Nê›æÉÍ¡(S\iûú»·óï‡DÑ‚/÷¶î©»·%î
+endobj
+893 0 obj
+699
+endobj
+894 0 obj<</Count 15/First 895 0 R/Last 1035 0 R>>endobj
+895 0 obj<</Parent 894 0 R/Title(Table of Contents)/Dest[882 0 R/XYZ null 756 null]/Next 896 0 R>>endobj
+896 0 obj<</Parent 894 0 R/Count -19/First 897 0 R/Last 915 0 R/Title(Chapter 1. How to Install and Test SAMBA)/Dest[639 0 R/XYZ null 750 null]/Prev 895 0 R/Next 916 0 R>>endobj
+897 0 obj<</Parent 896 0 R/Title(1.1. Step 0: Read the man pages)/Dest[639 0 R/XYZ null 726 null]/Next 898 0 R>>endobj
+898 0 obj<</Parent 896 0 R/Title(1.2. Step 1: Building the Binaries)/Dest[639 0 R/XYZ null 589 null]/Prev 897 0 R/Next 899 0 R>>endobj
+899 0 obj<</Parent 896 0 R/Title(1.3. Step 2: The all important step)/Dest[639 0 R/XYZ null 174 null]/Prev 898 0 R/Next 900 0 R>>endobj
+900 0 obj<</Parent 896 0 R/Title(1.4. Step 3: Create the smb configuration file.)/Dest[642 0 R/XYZ null 735 null]/Prev 899 0 R/Next 901 0 R>>endobj
+901 0 obj<</Parent 896 0 R/Title(1.5. Step 4: Test your config file with testparm)/Dest[642 0 R/XYZ null 375 null]/Prev 900 0 R/Next 902 0 R>>endobj
+902 0 obj<</Parent 896 0 R/Title(1.6. Step 5: Starting the smbd and nmbd)/Dest[642 0 R/XYZ null 264 null]/Prev 901 0 R/Next 903 0 R>>endobj
+903 0 obj<</Parent 896 0 R/Title(1.6.1. Step 5a: Starting from inetd.conf)/Dest[645 0 R/XYZ null 750 null]/Prev 902 0 R/Next 904 0 R>>endobj
+904 0 obj<</Parent 896 0 R/Title(1.6.2. Step 5b. Alternative: starting it as a daemon)/Dest[645 0 R/XYZ null 262 null]/Prev 903 0 R/Next 905 0 R>>endobj
+905 0 obj<</Parent 896 0 R/Title(1.7. Step 6: Try listing the shares available on your server)/Dest[648 0 R/XYZ null 682 null]/Prev 904 0 R/Next 906 0 R>>endobj
+906 0 obj<</Parent 896 0 R/Title(1.8. Step 7: Try connecting with the unix client)/Dest[648 0 R/XYZ null 505 null]/Prev 905 0 R/Next 907 0 R>>endobj
+907 0 obj<</Parent 896 0 R/Title(1.9. Step 8: Try connecting from a DOS, WfWg, Win9x, WinNT, Win2k, OS/2, etc... client)/Dest[648 0 R/XYZ null 328 null]/Prev 906 0 R/Next 908 0 R>>endobj
+908 0 obj<</Parent 896 0 R/Title(1.10. What If Things Don't Work?)/Dest[651 0 R/XYZ null 750 null]/Prev 907 0 R/Next 909 0 R>>endobj
+909 0 obj<</Parent 896 0 R/Title(1.10.1. Diagnosing Problems)/Dest[651 0 R/XYZ null 573 null]/Prev 908 0 R/Next 910 0 R>>endobj
+910 0 obj<</Parent 896 0 R/Title(1.10.2. Scope IDs)/Dest[651 0 R/XYZ null 501 null]/Prev 909 0 R/Next 911 0 R>>endobj
+911 0 obj<</Parent 896 0 R/Title(1.10.3. Choosing the Protocol Level)/Dest[651 0 R/XYZ null 390 null]/Prev 910 0 R/Next 912 0 R>>endobj
+912 0 obj<</Parent 896 0 R/Title(1.10.4. Printing from UNIX to a Client PC)/Dest[654 0 R/XYZ null 735 null]/Prev 911 0 R/Next 913 0 R>>endobj
+913 0 obj<</Parent 896 0 R/Title(1.10.5. Locking)/Dest[654 0 R/XYZ null 611 null]/Prev 912 0 R/Next 914 0 R>>endobj
+914 0 obj<</Parent 896 0 R/Title(1.10.6. Mapping Usernames)/Dest[657 0 R/XYZ null 750 null]/Prev 913 0 R/Next 915 0 R>>endobj
+915 0 obj<</Parent 896 0 R/Title(1.10.7. Other Character Sets)/Dest[657 0 R/XYZ null 679 null]/Prev 914 0 R>>endobj
+916 0 obj<</Parent 894 0 R/Count -18/First 917 0 R/Last 934 0 R/Title(Chapter 2. Integrating MS Windows networks with Samba)/Dest[660 0 R/XYZ null 750 null]/Prev 896 0 R/Next 935 0 R>>endobj
+917 0 obj<</Parent 916 0 R/Title(2.1. Agenda)/Dest[660 0 R/XYZ null 702 null]/Next 918 0 R>>endobj
+918 0 obj<</Parent 916 0 R/Title(2.2. Name Resolution in a pure Unix/Linux world)/Dest[660 0 R/XYZ null 459 null]/Prev 917 0 R/Next 919 0 R>>endobj
+919 0 obj<</Parent 916 0 R/Title(2.2.1. /etc/hosts)/Dest[660 0 R/XYZ null 321 null]/Prev 918 0 R/Next 920 0 R>>endobj
+920 0 obj<</Parent 916 0 R/Title(2.2.2. /etc/resolv.conf)/Dest[663 0 R/XYZ null 431 null]/Prev 919 0 R/Next 921 0 R>>endobj
+921 0 obj<</Parent 916 0 R/Title(2.2.3. /etc/host.conf)/Dest[663 0 R/XYZ null 281 null]/Prev 920 0 R/Next 922 0 R>>endobj
+922 0 obj<</Parent 916 0 R/Title(2.2.4. /etc/nsswitch.conf)/Dest[666 0 R/XYZ null 750 null]/Prev 921 0 R/Next 923 0 R>>endobj
+923 0 obj<</Parent 916 0 R/Title(2.3. Name resolution as used within MS Windows networking)/Dest[666 0 R/XYZ null 264 null]/Prev 922 0 R/Next 924 0 R>>endobj
+924 0 obj<</Parent 916 0 R/Title(2.3.1. The NetBIOS Name Cache)/Dest[669 0 R/XYZ null 206 null]/Prev 923 0 R/Next 925 0 R>>endobj
+925 0 obj<</Parent 916 0 R/Title(2.3.2. The LMHOSTS file)/Dest[672 0 R/XYZ null 656 null]/Prev 924 0 R/Next 926 0 R>>endobj
+926 0 obj<</Parent 916 0 R/Title(2.3.3. HOSTS file)/Dest[675 0 R/XYZ null 367 null]/Prev 925 0 R/Next 927 0 R>>endobj
+927 0 obj<</Parent 916 0 R/Title(2.3.4. DNS Lookup)/Dest[675 0 R/XYZ null 256 null]/Prev 926 0 R/Next 928 0 R>>endobj
+928 0 obj<</Parent 916 0 R/Title(2.3.5. WINS Lookup)/Dest[678 0 R/XYZ null 750 null]/Prev 927 0 R/Next 929 0 R>>endobj
+929 0 obj<</Parent 916 0 R/Title(2.4. How browsing functions and how to deploy stable and dependable browsing using Samba)/Dest[678 0 R/XYZ null 525 null]/Prev 928 0 R/Next 930 0 R>>endobj
+930 0 obj<</Parent 916 0 R/Title(2.5. MS Windows security options and how to configure Samba for seemless integration)/Dest[681 0 R/XYZ null 629 null]/Prev 929 0 R/Next 931 0 R>>endobj
+931 0 obj<</Parent 916 0 R/Title(2.5.1. Use MS Windows NT as an authentication server)/Dest[684 0 R/XYZ null 577 null]/Prev 930 0 R/Next 932 0 R>>endobj
+932 0 obj<</Parent 916 0 R/Title(2.5.2. Make Samba a member of an MS Windows NT security domain)/Dest[684 0 R/XYZ null 300 null]/Prev 931 0 R/Next 933 0 R>>endobj
+933 0 obj<</Parent 916 0 R/Title(2.5.3. Configure Samba as an authentication server)/Dest[687 0 R/XYZ null 590 null]/Prev 932 0 R/Next 934 0 R>>endobj
+934 0 obj<</Parent 916 0 R/Title(2.6. Conclusions)/Dest[690 0 R/XYZ null 635 null]/Prev 933 0 R>>endobj
+935 0 obj<</Parent 894 0 R/Count -3/First 936 0 R/Last 938 0 R/Title(Chapter 3. Configuring PAM for distributed but centrally managed authentication)/Dest[693 0 R/XYZ null 750 null]/Prev 916 0 R/Next 939 0 R>>endobj
+936 0 obj<</Parent 935 0 R/Title(3.1. Samba and PAM)/Dest[693 0 R/XYZ null 702 null]/Next 937 0 R>>endobj
+937 0 obj<</Parent 935 0 R/Title(3.2. Distributed Authentication)/Dest[696 0 R/XYZ null 175 null]/Prev 936 0 R/Next 938 0 R>>endobj
+938 0 obj<</Parent 935 0 R/Title(3.3. PAM Configuration in smb.conf)/Dest[699 0 R/XYZ null 722 null]/Prev 937 0 R>>endobj
+939 0 obj<</Parent 894 0 R/Count -2/First 940 0 R/Last 941 0 R/Title(Chapter 4. Hosting a Microsoft Distributed File System tree on Samba)/Dest[702 0 R/XYZ null 750 null]/Prev 935 0 R/Next 942 0 R>>endobj
+940 0 obj<</Parent 939 0 R/Title(4.1. Instructions)/Dest[702 0 R/XYZ null 702 null]/Next 941 0 R>>endobj
+941 0 obj<</Parent 939 0 R/Title(4.1.1. Notes)/Dest[705 0 R/XYZ null 669 null]/Prev 940 0 R>>endobj
+942 0 obj<</Parent 894 0 R/Count -9/First 943 0 R/Last 951 0 R/Title(Chapter 5. UNIX Permission Bits and Windows NT Access Control Lists)/Dest[708 0 R/XYZ null 750 null]/Prev 939 0 R/Next 952 0 R>>endobj
+943 0 obj<</Parent 942 0 R/Title(5.1. Viewing and changing UNIX permissions using the NT security dialogs)/Dest[708 0 R/XYZ null 702 null]/Next 944 0 R>>endobj
+944 0 obj<</Parent 942 0 R/Title(5.2. How to view file security on a Samba share)/Dest[708 0 R/XYZ null 521 null]/Prev 943 0 R/Next 945 0 R>>endobj
+945 0 obj<</Parent 942 0 R/Title(5.3. Viewing file ownership)/Dest[708 0 R/XYZ null 344 null]/Prev 944 0 R/Next 946 0 R>>endobj
+946 0 obj<</Parent 942 0 R/Title(5.4. Viewing file or directory permissions)/Dest[711 0 R/XYZ null 682 null]/Prev 945 0 R/Next 947 0 R>>endobj
+947 0 obj<</Parent 942 0 R/Title(5.4.1. File Permissions)/Dest[711 0 R/XYZ null 439 null]/Prev 946 0 R/Next 948 0 R>>endobj
+948 0 obj<</Parent 942 0 R/Title(5.4.2. Directory Permissions)/Dest[711 0 R/XYZ null 183 null]/Prev 947 0 R/Next 949 0 R>>endobj
+949 0 obj<</Parent 942 0 R/Title(5.5. Modifying file or directory permissions)/Dest[714 0 R/XYZ null 669 null]/Prev 948 0 R/Next 950 0 R>>endobj
+950 0 obj<</Parent 942 0 R/Title(5.6. Interaction with the standard Samba create mask parameters)/Dest[714 0 R/XYZ null 228 null]/Prev 949 0 R/Next 951 0 R>>endobj
+951 0 obj<</Parent 942 0 R/Title(5.7. Interaction with the standard Samba file attribute mapping)/Dest[720 0 R/XYZ null 590 null]/Prev 950 0 R>>endobj
+952 0 obj<</Parent 894 0 R/Count -13/First 953 0 R/Last 965 0 R/Title(Chapter 6. Printing Support in Samba 2.2.x)/Dest[723 0 R/XYZ null 750 null]/Prev 942 0 R/Next 966 0 R>>endobj
+953 0 obj<</Parent 952 0 R/Title(6.1. Introduction)/Dest[723 0 R/XYZ null 726 null]/Next 954 0 R>>endobj
+954 0 obj<</Parent 952 0 R/Title(6.2. Configuration)/Dest[723 0 R/XYZ null 298 null]/Prev 953 0 R/Next 955 0 R>>endobj
+955 0 obj<</Parent 952 0 R/Title(6.2.1. Creating [print$])/Dest[726 0 R/XYZ null 689 null]/Prev 954 0 R/Next 956 0 R>>endobj
+956 0 obj<</Parent 952 0 R/Title(6.2.2. Setting Drivers for Existing Printers)/Dest[729 0 R/XYZ null 446 null]/Prev 955 0 R/Next 957 0 R>>endobj
+957 0 obj<</Parent 952 0 R/Title(6.2.3. Support a large number of printers)/Dest[732 0 R/XYZ null 682 null]/Prev 956 0 R/Next 958 0 R>>endobj
+958 0 obj<</Parent 952 0 R/Title(6.2.4. Adding New Printers via the Windows NT APW)/Dest[732 0 R/XYZ null 298 null]/Prev 957 0 R/Next 959 0 R>>endobj
+959 0 obj<</Parent 952 0 R/Title(6.2.5. Samba and Printer Ports)/Dest[735 0 R/XYZ null 682 null]/Prev 958 0 R/Next 960 0 R>>endobj
+960 0 obj<</Parent 952 0 R/Title(6.3. The Imprints Toolset)/Dest[735 0 R/XYZ null 492 null]/Prev 959 0 R/Next 961 0 R>>endobj
+961 0 obj<</Parent 952 0 R/Title(6.3.1. What is Imprints?)/Dest[735 0 R/XYZ null 381 null]/Prev 960 0 R/Next 962 0 R>>endobj
+962 0 obj<</Parent 952 0 R/Title(6.3.2. Creating Printer Driver Packages)/Dest[735 0 R/XYZ null 243 null]/Prev 961 0 R/Next 963 0 R>>endobj
+963 0 obj<</Parent 952 0 R/Title(6.3.3. The Imprints server)/Dest[735 0 R/XYZ null 145 null]/Prev 962 0 R/Next 964 0 R>>endobj
+964 0 obj<</Parent 952 0 R/Title(6.3.4. The Installation Client)/Dest[738 0 R/XYZ null 709 null]/Prev 963 0 R/Next 965 0 R>>endobj
+965 0 obj<</Parent 952 0 R/Title(6.4. Migration to from Samba 2.0.x to 2.2.x)/Dest[741 0 R/XYZ null 750 null]/Prev 964 0 R>>endobj
+966 0 obj<</Parent 894 0 R/Count -3/First 967 0 R/Last 969 0 R/Title(Chapter 7. security = domain in Samba 2.x)/Dest[744 0 R/XYZ null 750 null]/Prev 952 0 R/Next 970 0 R>>endobj
+967 0 obj<</Parent 966 0 R/Title(7.1. Joining an NT Domain with Samba 2.2)/Dest[744 0 R/XYZ null 726 null]/Next 968 0 R>>endobj
+968 0 obj<</Parent 966 0 R/Title(7.2. Samba and Windows 2000 Domains)/Dest[747 0 R/XYZ null 379 null]/Prev 967 0 R/Next 969 0 R>>endobj
+969 0 obj<</Parent 966 0 R/Title(7.3. Why is this better than security = server?)/Dest[747 0 R/XYZ null 162 null]/Prev 968 0 R>>endobj
+970 0 obj<</Parent 894 0 R/Count -14/First 971 0 R/Last 984 0 R/Title(Chapter 8. How to Configure Samba 2.2 as a Primary Domain Controller)/Dest[753 0 R/XYZ null 750 null]/Prev 966 0 R/Next 985 0 R>>endobj
+971 0 obj<</Parent 970 0 R/Title(8.1. Prerequisite Reading)/Dest[753 0 R/XYZ null 702 null]/Next 972 0 R>>endobj
+972 0 obj<</Parent 970 0 R/Title(8.2. Background)/Dest[753 0 R/XYZ null 604 null]/Prev 971 0 R/Next 973 0 R>>endobj
+973 0 obj<</Parent 970 0 R/Title(8.3. Configuring the Samba Domain Controller)/Dest[756 0 R/XYZ null 722 null]/Prev 972 0 R/Next 974 0 R>>endobj
+974 0 obj<</Parent 970 0 R/Title(8.4. Creating Machine Trust Accounts and Joining Clients to the Domain)/Dest[759 0 R/XYZ null 603 null]/Prev 973 0 R/Next 975 0 R>>endobj
+975 0 obj<</Parent 970 0 R/Title(8.4.1. Manual Creation of Machine Trust Accounts)/Dest[759 0 R/XYZ null 228 null]/Prev 974 0 R/Next 976 0 R>>endobj
+976 0 obj<</Parent 970 0 R/Title(8.4.2. "On-the-Fly" Creation of Machine Trust Accounts)/Dest[762 0 R/XYZ null 355 null]/Prev 975 0 R/Next 977 0 R>>endobj
+977 0 obj<</Parent 970 0 R/Title(8.4.3. Joining the Client to the Domain)/Dest[765 0 R/XYZ null 750 null]/Prev 976 0 R/Next 978 0 R>>endobj
+978 0 obj<</Parent 970 0 R/Title(8.5. Common Problems and Errors)/Dest[765 0 R/XYZ null 388 null]/Prev 977 0 R/Next 979 0 R>>endobj
+979 0 obj<</Parent 970 0 R/Title(8.6. System Policies and Profiles)/Dest[771 0 R/XYZ null 735 null]/Prev 978 0 R/Next 980 0 R>>endobj
+980 0 obj<</Parent 970 0 R/Title(8.7. What other help can I get?)/Dest[774 0 R/XYZ null 682 null]/Prev 979 0 R/Next 981 0 R>>endobj
+981 0 obj<</Parent 970 0 R/Title(8.8. Domain Control for Windows 9x/ME)/Dest[780 0 R/XYZ null 299 null]/Prev 980 0 R/Next 982 0 R>>endobj
+982 0 obj<</Parent 970 0 R/Title(8.8.1. Configuration Instructions: Network Logons)/Dest[783 0 R/XYZ null 273 null]/Prev 981 0 R/Next 983 0 R>>endobj
+983 0 obj<</Parent 970 0 R/Title(8.8.2. Configuration Instructions: Setting up Roaming User Profiles)/Dest[786 0 R/XYZ null 478 null]/Prev 982 0 R/Next 984 0 R>>endobj
+984 0 obj<</Parent 970 0 R/Title(8.9. DOMAIN_CONTROL.txt : Windows NT Domain Control & Samba)/Dest[798 0 R/XYZ null 270 null]/Prev 983 0 R>>endobj
+985 0 obj<</Parent 894 0 R/Count -8/First 986 0 R/Last 993 0 R/Title(Chapter 9. How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain)/Dest[807 0 R/XYZ null 750 null]/Prev 970 0 R/Next 994 0 R>>endobj
+986 0 obj<</Parent 985 0 R/Title(9.1. Prerequisite Reading)/Dest[807 0 R/XYZ null 702 null]/Next 987 0 R>>endobj
+987 0 obj<</Parent 985 0 R/Title(9.2. Background)/Dest[807 0 R/XYZ null 617 null]/Prev 986 0 R/Next 988 0 R>>endobj
+988 0 obj<</Parent 985 0 R/Title(9.3. What qualifies a Domain Controller on the network?)/Dest[807 0 R/XYZ null 235 null]/Prev 987 0 R/Next 989 0 R>>endobj
+989 0 obj<</Parent 985 0 R/Title(9.3.1. How does a Workstation find its domain controller?)/Dest[810 0 R/XYZ null 750 null]/Prev 988 0 R/Next 990 0 R>>endobj
+990 0 obj<</Parent 985 0 R/Title(9.3.2. When is the PDC needed?)/Dest[810 0 R/XYZ null 626 null]/Prev 989 0 R/Next 991 0 R>>endobj
+991 0 obj<</Parent 985 0 R/Title(9.4. Can Samba be a Backup Domain Controller?)/Dest[810 0 R/XYZ null 528 null]/Prev 990 0 R/Next 992 0 R>>endobj
+992 0 obj<</Parent 985 0 R/Title(9.5. How do I set up a Samba BDC?)/Dest[810 0 R/XYZ null 377 null]/Prev 991 0 R/Next 993 0 R>>endobj
+993 0 obj<</Parent 985 0 R/Title(9.5.1. How do I replicate the smbpasswd file?)/Dest[813 0 R/XYZ null 646 null]/Prev 992 0 R>>endobj
+994 0 obj<</Parent 894 0 R/Count -12/First 995 0 R/Last 1006 0 R/Title(Chapter 10. Storing Samba's User/Machine Account information in an LDAP Directory)/Dest[816 0 R/XYZ null 750 null]/Prev 985 0 R/Next 1007 0 R>>endobj
+995 0 obj<</Parent 994 0 R/Title(10.1. Purpose)/Dest[816 0 R/XYZ null 702 null]/Next 996 0 R>>endobj
+996 0 obj<</Parent 994 0 R/Title(10.2. Introduction)/Dest[816 0 R/XYZ null 433 null]/Prev 995 0 R/Next 997 0 R>>endobj
+997 0 obj<</Parent 994 0 R/Title(10.3. Supported LDAP Servers)/Dest[819 0 R/XYZ null 577 null]/Prev 996 0 R/Next 998 0 R>>endobj
+998 0 obj<</Parent 994 0 R/Title(10.4. Schema and Relationship to the RFC 2307 posixAccount)/Dest[819 0 R/XYZ null 465 null]/Prev 997 0 R/Next 999 0 R>>endobj
+999 0 obj<</Parent 994 0 R/Title(10.5. Configuring Samba with LDAP)/Dest[822 0 R/XYZ null 735 null]/Prev 998 0 R/Next 1000 0 R>>endobj
+1000 0 obj<</Parent 994 0 R/Title(10.5.1. OpenLDAP configuration)/Dest[822 0 R/XYZ null 705 null]/Prev 999 0 R/Next 1001 0 R>>endobj
+1001 0 obj<</Parent 994 0 R/Title(10.5.2. Configuring Samba)/Dest[825 0 R/XYZ null 750 null]/Prev 1000 0 R/Next 1002 0 R>>endobj
+1002 0 obj<</Parent 994 0 R/Title(10.6. Accounts and Groups management)/Dest[825 0 R/XYZ null 176 null]/Prev 1001 0 R/Next 1003 0 R>>endobj
+1003 0 obj<</Parent 994 0 R/Title(10.7. Security and sambaAccount)/Dest[828 0 R/XYZ null 629 null]/Prev 1002 0 R/Next 1004 0 R>>endobj
+1004 0 obj<</Parent 994 0 R/Title(10.8. LDAP specials attributes for sambaAccounts)/Dest[828 0 R/XYZ null 236 null]/Prev 1003 0 R/Next 1005 0 R>>endobj
+1005 0 obj<</Parent 994 0 R/Title(10.9. Example LDIF Entries for a sambaAccount)/Dest[831 0 R/XYZ null 207 null]/Prev 1004 0 R/Next 1006 0 R>>endobj
+1006 0 obj<</Parent 994 0 R/Title(10.10. Comments)/Dest[834 0 R/XYZ null 358 null]/Prev 1005 0 R>>endobj
+1007 0 obj<</Parent 894 0 R/Count -16/First 1008 0 R/Last 1023 0 R/Title(Chapter 11. Unified Logons between Windows NT and UNIX using Winbind)/Dest[837 0 R/XYZ null 750 null]/Prev 994 0 R/Next 1024 0 R>>endobj
+1008 0 obj<</Parent 1007 0 R/Title(11.1. Abstract)/Dest[837 0 R/XYZ null 702 null]/Next 1009 0 R>>endobj
+1009 0 obj<</Parent 1007 0 R/Title(11.2. Introduction)/Dest[837 0 R/XYZ null 565 null]/Prev 1008 0 R/Next 1010 0 R>>endobj
+1010 0 obj<</Parent 1007 0 R/Title(11.3. What Winbind Provides)/Dest[837 0 R/XYZ null 242 null]/Prev 1009 0 R/Next 1011 0 R>>endobj
+1011 0 obj<</Parent 1007 0 R/Title(11.3.1. Target Uses)/Dest[840 0 R/XYZ null 577 null]/Prev 1010 0 R/Next 1012 0 R>>endobj
+1012 0 obj<</Parent 1007 0 R/Title(11.4. How Winbind Works)/Dest[840 0 R/XYZ null 413 null]/Prev 1011 0 R/Next 1013 0 R>>endobj
+1013 0 obj<</Parent 1007 0 R/Title(11.4.1. Microsoft Remote Procedure Calls)/Dest[840 0 R/XYZ null 288 null]/Prev 1012 0 R/Next 1014 0 R>>endobj
+1014 0 obj<</Parent 1007 0 R/Title(11.4.2. Name Service Switch)/Dest[843 0 R/XYZ null 750 null]/Prev 1013 0 R/Next 1015 0 R>>endobj
+1015 0 obj<</Parent 1007 0 R/Title(11.4.3. Pluggable Authentication Modules)/Dest[843 0 R/XYZ null 309 null]/Prev 1014 0 R/Next 1016 0 R>>endobj
+1016 0 obj<</Parent 1007 0 R/Title(11.4.4. User and Group ID Allocation)/Dest[846 0 R/XYZ null 669 null]/Prev 1015 0 R/Next 1017 0 R>>endobj
+1017 0 obj<</Parent 1007 0 R/Title(11.4.5. Result Caching)/Dest[846 0 R/XYZ null 479 null]/Prev 1016 0 R/Next 1018 0 R>>endobj
+1018 0 obj<</Parent 1007 0 R/Title(11.5. Installation and Configuration)/Dest[846 0 R/XYZ null 328 null]/Prev 1017 0 R/Next 1019 0 R>>endobj
+1019 0 obj<</Parent 1007 0 R/Title(11.5.1. Introduction)/Dest[846 0 R/XYZ null 217 null]/Prev 1018 0 R/Next 1020 0 R>>endobj
+1020 0 obj<</Parent 1007 0 R/Title(11.5.2. Requirements)/Dest[849 0 R/XYZ null 577 null]/Prev 1019 0 R/Next 1021 0 R>>endobj
+1021 0 obj<</Parent 1007 0 R/Title(11.5.3. Testing Things Out)/Dest[849 0 R/XYZ null 294 null]/Prev 1020 0 R/Next 1022 0 R>>endobj
+1022 0 obj<</Parent 1007 0 R/Title(11.6. Limitations)/Dest[864 0 R/XYZ null 351 null]/Prev 1021 0 R/Next 1023 0 R>>endobj
+1023 0 obj<</Parent 1007 0 R/Title(11.7. Conclusion)/Dest[867 0 R/XYZ null 750 null]/Prev 1022 0 R>>endobj
+1024 0 obj<</Parent 894 0 R/Count -5/First 1025 0 R/Last 1029 0 R/Title(Chapter 12. OS2 Client HOWTO)/Dest[870 0 R/XYZ null 750 null]/Prev 1007 0 R/Next 1030 0 R>>endobj
+1025 0 obj<</Parent 1024 0 R/Title(12.1. FAQs)/Dest[870 0 R/XYZ null 726 null]/Next 1026 0 R>>endobj
+1026 0 obj<</Parent 1024 0 R/Title(12.1.1. How can I configure OS/2 Warp Connect or OS/2 Warp 4 as a client for Samba?)/Dest[870 0 R/XYZ null 696 null]/Prev 1025 0 R/Next 1027 0 R>>endobj
+1027 0 obj<</Parent 1024 0 R/Title(12.1.2. How can I configure OS/2 Warp 3 \(not Connect\), OS/2 1.2, 1.3 or 2.x for Samba?)/Dest[870 0 R/XYZ null 344 null]/Prev 1026 0 R/Next 1028 0 R>>endobj
+1028 0 obj<</Parent 1024 0 R/Title(12.1.3. Are there any other issues when OS/2 \(any version\) is used as a client?)/Dest[873 0 R/XYZ null 750 null]/Prev 1027 0 R/Next 1029 0 R>>endobj
+1029 0 obj<</Parent 1024 0 R/Title(12.1.4. How do I get printer driver download working for OS/2 clients?)/Dest[873 0 R/XYZ null 635 null]/Prev 1028 0 R>>endobj
+1030 0 obj<</Parent 894 0 R/Count -4/First 1031 0 R/Last 1034 0 R/Title(Chapter 13. HOWTO Access Samba source code via CVS)/Dest[876 0 R/XYZ null 750 null]/Prev 1024 0 R/Next 1035 0 R>>endobj
+1031 0 obj<</Parent 1030 0 R/Title(13.1. Introduction)/Dest[876 0 R/XYZ null 702 null]/Next 1032 0 R>>endobj
+1032 0 obj<</Parent 1030 0 R/Title(13.2. CVS Access to samba.org)/Dest[876 0 R/XYZ null 578 null]/Prev 1031 0 R/Next 1033 0 R>>endobj
+1033 0 obj<</Parent 1030 0 R/Title(13.2.1. Access via CVSweb)/Dest[876 0 R/XYZ null 480 null]/Prev 1032 0 R/Next 1034 0 R>>endobj
+1034 0 obj<</Parent 1030 0 R/Title(13.2.2. Access via cvs)/Dest[876 0 R/XYZ null 355 null]/Prev 1033 0 R>>endobj
+1035 0 obj<</Parent 894 0 R/Title(Index)/Dest[879 0 R/XYZ null 484 null]/Prev 1030 0 R>>endobj
+1036 0 obj<</Type/Catalog/Pages 635 0 R/Names 471 0 R/PageLayout/SinglePage/Outlines 894 0 R/OpenAction[636 0 R/XYZ null null null]/PageMode/UseOutlines/PageLabels<</Nums[0<</P(title)>>1<</S/r>>5<</S/D>>]>>>>endobj
xref
-0 1367
+0 1037
0000000000 65535 f
0000000015 00000 n
0000000244 00000 n
@@ -3053,1351 +2350,1021 @@ xref
0000003097 00000 n
0000003182 00000 n
0000003206 00000 n
-0000003259 00000 n
-0000003344 00000 n
-0000003397 00000 n
-0000003482 00000 n
-0000003513 00000 n
-0000003559 00000 n
-0000003644 00000 n
-0000003689 00000 n
-0000003773 00000 n
-0000003818 00000 n
-0000003902 00000 n
-0000003940 00000 n
-0000003983 00000 n
-0000004068 00000 n
-0000004111 00000 n
-0000004195 00000 n
-0000004226 00000 n
-0000004280 00000 n
-0000004364 00000 n
-0000004388 00000 n
-0000004439 00000 n
-0000004524 00000 n
-0000004572 00000 n
-0000004657 00000 n
-0000004688 00000 n
-0000004806 00000 n
-0000004890 00000 n
-0000004931 00000 n
-0000005016 00000 n
-0000005057 00000 n
-0000005142 00000 n
-0000005180 00000 n
-0000005224 00000 n
-0000005309 00000 n
-0000005333 00000 n
-0000005377 00000 n
-0000005461 00000 n
-0000005503 00000 n
-0000005588 00000 n
-0000005637 00000 n
-0000005722 00000 n
-0000005771 00000 n
-0000005854 00000 n
-0000005901 00000 n
-0000005986 00000 n
-0000006032 00000 n
-0000006116 00000 n
-0000006175 00000 n
-0000006237 00000 n
-0000006322 00000 n
-0000006379 00000 n
-0000006464 00000 n
-0000006557 00000 n
-0000006641 00000 n
-0000006679 00000 n
-0000006784 00000 n
-0000006825 00000 n
-0000006909 00000 n
-0000006955 00000 n
-0000007040 00000 n
-0000007079 00000 n
-0000007164 00000 n
-0000007206 00000 n
-0000007291 00000 n
-0000007333 00000 n
-0000007418 00000 n
-0000007477 00000 n
-0000007521 00000 n
-0000007606 00000 n
-0000007630 00000 n
-0000007677 00000 n
-0000007762 00000 n
-0000007814 00000 n
-0000007899 00000 n
-0000007948 00000 n
-0000008033 00000 n
-0000008082 00000 n
-0000008167 00000 n
-0000008214 00000 n
-0000008267 00000 n
-0000008354 00000 n
-0000008403 00000 n
-0000008490 00000 n
-0000008539 00000 n
-0000008625 00000 n
-0000008689 00000 n
-0000008776 00000 n
-0000008826 00000 n
-0000008890 00000 n
-0000008977 00000 n
-0000009003 00000 n
-0000009044 00000 n
-0000009130 00000 n
-0000009180 00000 n
-0000009266 00000 n
-0000009312 00000 n
-0000009399 00000 n
-0000009441 00000 n
-0000009489 00000 n
-0000009576 00000 n
-0000009623 00000 n
-0000009710 00000 n
-0000009751 00000 n
+0000003252 00000 n
+0000003337 00000 n
+0000003382 00000 n
+0000003466 00000 n
+0000003511 00000 n
+0000003595 00000 n
+0000003633 00000 n
+0000003676 00000 n
+0000003761 00000 n
+0000003804 00000 n
+0000003888 00000 n
+0000003919 00000 n
+0000003973 00000 n
+0000004057 00000 n
+0000004081 00000 n
+0000004132 00000 n
+0000004217 00000 n
+0000004265 00000 n
+0000004350 00000 n
+0000004381 00000 n
+0000004499 00000 n
+0000004583 00000 n
+0000004624 00000 n
+0000004709 00000 n
+0000004750 00000 n
+0000004835 00000 n
+0000004873 00000 n
+0000004917 00000 n
+0000005002 00000 n
+0000005026 00000 n
+0000005070 00000 n
+0000005154 00000 n
+0000005196 00000 n
+0000005281 00000 n
+0000005330 00000 n
+0000005415 00000 n
+0000005464 00000 n
+0000005547 00000 n
+0000005594 00000 n
+0000005679 00000 n
+0000005725 00000 n
+0000005809 00000 n
+0000005868 00000 n
+0000005930 00000 n
+0000006015 00000 n
+0000006072 00000 n
+0000006157 00000 n
+0000006250 00000 n
+0000006334 00000 n
+0000006372 00000 n
+0000006477 00000 n
+0000006518 00000 n
+0000006602 00000 n
+0000006648 00000 n
+0000006733 00000 n
+0000006772 00000 n
+0000006857 00000 n
+0000006899 00000 n
+0000006984 00000 n
+0000007026 00000 n
+0000007111 00000 n
+0000007170 00000 n
+0000007214 00000 n
+0000007299 00000 n
+0000007323 00000 n
+0000007370 00000 n
+0000007455 00000 n
+0000007507 00000 n
+0000007592 00000 n
+0000007641 00000 n
+0000007726 00000 n
+0000007775 00000 n
+0000007859 00000 n
+0000007904 00000 n
+0000007956 00000 n
+0000008041 00000 n
+0000008089 00000 n
+0000008175 00000 n
+0000008224 00000 n
+0000008310 00000 n
+0000008374 00000 n
+0000008461 00000 n
+0000008510 00000 n
+0000008574 00000 n
+0000008661 00000 n
+0000008687 00000 n
+0000008735 00000 n
+0000008822 00000 n
+0000008869 00000 n
+0000008956 00000 n
+0000008997 00000 n
+0000009083 00000 n
+0000009125 00000 n
+0000009167 00000 n
+0000009254 00000 n
+0000009303 00000 n
+0000009390 00000 n
+0000009437 00000 n
+0000009524 00000 n
+0000009566 00000 n
+0000009619 00000 n
+0000009706 00000 n
+0000009750 00000 n
0000009837 00000 n
-0000009879 00000 n
-0000009921 00000 n
-0000010008 00000 n
-0000010057 00000 n
-0000010144 00000 n
-0000010191 00000 n
-0000010278 00000 n
-0000010320 00000 n
-0000010373 00000 n
-0000010460 00000 n
-0000010504 00000 n
-0000010591 00000 n
-0000010648 00000 n
-0000010735 00000 n
-0000010831 00000 n
-0000010917 00000 n
-0000010967 00000 n
-0000011029 00000 n
-0000011116 00000 n
-0000011142 00000 n
-0000011191 00000 n
-0000011278 00000 n
-0000011304 00000 n
-0000011351 00000 n
-0000011436 00000 n
-0000011462 00000 n
-0000011511 00000 n
-0000011598 00000 n
-0000011641 00000 n
-0000011728 00000 n
-0000011771 00000 n
-0000011858 00000 n
-0000011907 00000 n
-0000011994 00000 n
-0000012043 00000 n
-0000012130 00000 n
-0000012178 00000 n
-0000012265 00000 n
-0000012311 00000 n
-0000012398 00000 n
-0000012472 00000 n
-0000012519 00000 n
-0000012606 00000 n
-0000012653 00000 n
-0000012740 00000 n
-0000012789 00000 n
-0000012876 00000 n
-0000012923 00000 n
-0000013010 00000 n
-0000013060 00000 n
-0000013107 00000 n
-0000013194 00000 n
-0000013241 00000 n
-0000013326 00000 n
-0000013370 00000 n
-0000013456 00000 n
-0000013498 00000 n
-0000013584 00000 n
-0000013624 00000 n
-0000013710 00000 n
-0000013758 00000 n
-0000013844 00000 n
-0000013889 00000 n
-0000013975 00000 n
-0000014019 00000 n
-0000014105 00000 n
-0000014156 00000 n
-0000014242 00000 n
-0000014291 00000 n
-0000014377 00000 n
-0000014422 00000 n
-0000014508 00000 n
-0000014550 00000 n
-0000014636 00000 n
-0000014679 00000 n
-0000014765 00000 n
-0000014807 00000 n
-0000014893 00000 n
-0000014937 00000 n
-0000015023 00000 n
-0000015060 00000 n
-0000015146 00000 n
-0000015187 00000 n
-0000015273 00000 n
-0000015315 00000 n
-0000015401 00000 n
-0000015438 00000 n
-0000015524 00000 n
-0000015565 00000 n
-0000015651 00000 n
-0000015694 00000 n
-0000015780 00000 n
-0000015826 00000 n
-0000015912 00000 n
-0000016106 00000 n
-0000016153 00000 n
-0000016240 00000 n
-0000016289 00000 n
-0000016376 00000 n
-0000016425 00000 n
-0000016511 00000 n
-0000016553 00000 n
-0000016601 00000 n
-0000016687 00000 n
-0000016733 00000 n
-0000016820 00000 n
-0000016854 00000 n
-0000016969 00000 n
-0000017056 00000 n
-0000017082 00000 n
+0000009894 00000 n
+0000009981 00000 n
+0000010077 00000 n
+0000010163 00000 n
+0000010213 00000 n
+0000010260 00000 n
+0000010347 00000 n
+0000010394 00000 n
+0000010481 00000 n
+0000010530 00000 n
+0000010617 00000 n
+0000010664 00000 n
+0000010751 00000 n
+0000010801 00000 n
+0000010848 00000 n
+0000010935 00000 n
+0000010982 00000 n
+0000011067 00000 n
+0000011111 00000 n
+0000011197 00000 n
+0000011239 00000 n
+0000011325 00000 n
+0000011365 00000 n
+0000011451 00000 n
+0000011499 00000 n
+0000011585 00000 n
+0000011630 00000 n
+0000011716 00000 n
+0000011760 00000 n
+0000011846 00000 n
+0000011897 00000 n
+0000011983 00000 n
+0000012032 00000 n
+0000012118 00000 n
+0000012163 00000 n
+0000012249 00000 n
+0000012291 00000 n
+0000012377 00000 n
+0000012420 00000 n
+0000012506 00000 n
+0000012548 00000 n
+0000012634 00000 n
+0000012678 00000 n
+0000012764 00000 n
+0000012801 00000 n
+0000012887 00000 n
+0000012928 00000 n
+0000013014 00000 n
+0000013056 00000 n
+0000013142 00000 n
+0000013179 00000 n
+0000013265 00000 n
+0000013306 00000 n
+0000013392 00000 n
+0000013435 00000 n
+0000013521 00000 n
+0000013567 00000 n
+0000013653 00000 n
+0000013847 00000 n
+0000013894 00000 n
+0000013981 00000 n
+0000014030 00000 n
+0000014117 00000 n
+0000014166 00000 n
+0000014252 00000 n
+0000014294 00000 n
+0000014342 00000 n
+0000014428 00000 n
+0000014474 00000 n
+0000014561 00000 n
+0000014595 00000 n
+0000014710 00000 n
+0000014797 00000 n
+0000014823 00000 n
+0000014905 00000 n
+0000014992 00000 n
+0000015077 00000 n
+0000015164 00000 n
+0000015219 00000 n
+0000015306 00000 n
+0000015362 00000 n
+0000015449 00000 n
+0000015499 00000 n
+0000015547 00000 n
+0000015634 00000 n
+0000015708 00000 n
+0000015795 00000 n
+0000015863 00000 n
+0000015950 00000 n
+0000016004 00000 n
+0000016091 00000 n
+0000016159 00000 n
+0000016246 00000 n
+0000016320 00000 n
+0000016407 00000 n
+0000016455 00000 n
+0000016542 00000 n
+0000016599 00000 n
+0000016686 00000 n
+0000016768 00000 n
+0000016823 00000 n
+0000016910 00000 n
+0000016991 00000 n
+0000017078 00000 n
+0000017112 00000 n
0000017164 00000 n
0000017251 00000 n
-0000017336 00000 n
-0000017423 00000 n
-0000017478 00000 n
-0000017565 00000 n
-0000017621 00000 n
-0000017708 00000 n
-0000017758 00000 n
-0000017806 00000 n
-0000017893 00000 n
-0000017967 00000 n
-0000018054 00000 n
-0000018122 00000 n
-0000018209 00000 n
-0000018263 00000 n
-0000018350 00000 n
-0000018418 00000 n
-0000018505 00000 n
-0000018579 00000 n
-0000018666 00000 n
-0000018714 00000 n
-0000018801 00000 n
-0000018858 00000 n
-0000018945 00000 n
-0000019027 00000 n
-0000019082 00000 n
-0000019169 00000 n
-0000019250 00000 n
-0000019337 00000 n
-0000019371 00000 n
-0000019423 00000 n
-0000019510 00000 n
-0000019536 00000 n
-0000019592 00000 n
-0000019679 00000 n
-0000019748 00000 n
-0000019835 00000 n
-0000019886 00000 n
-0000019973 00000 n
-0000020060 00000 n
-0000020147 00000 n
-0000020203 00000 n
-0000020290 00000 n
-0000020339 00000 n
-0000020426 00000 n
-0000020492 00000 n
-0000020544 00000 n
-0000020631 00000 n
-0000020686 00000 n
-0000020773 00000 n
-0000020820 00000 n
-0000020907 00000 n
-0000020954 00000 n
-0000021041 00000 n
-0000021091 00000 n
-0000021131 00000 n
-0000021218 00000 n
-0000021261 00000 n
-0000021348 00000 n
-0000021392 00000 n
-0000021479 00000 n
-0000021522 00000 n
-0000021609 00000 n
-0000021652 00000 n
-0000021739 00000 n
-0000021780 00000 n
-0000021867 00000 n
-0000021914 00000 n
-0000022001 00000 n
-0000022075 00000 n
-0000022122 00000 n
-0000022208 00000 n
-0000022234 00000 n
-0000022286 00000 n
-0000022372 00000 n
-0000022398 00000 n
-0000022452 00000 n
-0000022539 00000 n
-0000022565 00000 n
-0000022644 00000 n
-0000022731 00000 n
-0000022813 00000 n
-0000022899 00000 n
-0000022974 00000 n
-0000023061 00000 n
-0000023134 00000 n
-0000023221 00000 n
-0000023271 00000 n
-0000023349 00000 n
-0000023436 00000 n
-0000023462 00000 n
-0000023525 00000 n
-0000023612 00000 n
-0000023675 00000 n
-0000023762 00000 n
-0000023816 00000 n
-0000023903 00000 n
-0000023945 00000 n
-0000023991 00000 n
-0000024078 00000 n
-0000024104 00000 n
-0000024145 00000 n
-0000024232 00000 n
-0000024258 00000 n
-0000024363 00000 n
-0000024469 00000 n
-0000024575 00000 n
-0000024681 00000 n
-0000024787 00000 n
-0000024893 00000 n
-0000024999 00000 n
-0000025105 00000 n
-0000025211 00000 n
-0000025317 00000 n
-0000025423 00000 n
-0000025529 00000 n
-0000025635 00000 n
-0000025741 00000 n
-0000025847 00000 n
-0000025953 00000 n
-0000026059 00000 n
-0000026165 00000 n
-0000026271 00000 n
-0000026376 00000 n
-0000026482 00000 n
-0000026588 00000 n
-0000026694 00000 n
-0000026800 00000 n
-0000026906 00000 n
-0000027012 00000 n
-0000027118 00000 n
-0000027224 00000 n
-0000027330 00000 n
-0000027436 00000 n
-0000027542 00000 n
-0000027648 00000 n
-0000027754 00000 n
-0000027860 00000 n
-0000027966 00000 n
-0000028071 00000 n
-0000028177 00000 n
-0000028283 00000 n
-0000028389 00000 n
-0000028495 00000 n
-0000028601 00000 n
-0000028707 00000 n
-0000028813 00000 n
-0000028918 00000 n
-0000029022 00000 n
-0000029126 00000 n
-0000029512 00000 n
-0000029618 00000 n
-0000029724 00000 n
-0000029830 00000 n
-0000029936 00000 n
-0000030042 00000 n
-0000030148 00000 n
-0000030254 00000 n
-0000030360 00000 n
-0000030465 00000 n
-0000030571 00000 n
-0000030677 00000 n
-0000030783 00000 n
-0000030888 00000 n
-0000030994 00000 n
-0000031100 00000 n
-0000031205 00000 n
-0000031311 00000 n
-0000031417 00000 n
-0000031523 00000 n
-0000031629 00000 n
-0000031735 00000 n
-0000031841 00000 n
-0000031947 00000 n
-0000032053 00000 n
-0000032159 00000 n
-0000032264 00000 n
-0000032370 00000 n
-0000032476 00000 n
-0000032582 00000 n
-0000032688 00000 n
-0000032794 00000 n
-0000032900 00000 n
-0000033006 00000 n
-0000033112 00000 n
-0000033218 00000 n
-0000033324 00000 n
-0000033430 00000 n
-0000033536 00000 n
-0000033642 00000 n
-0000033747 00000 n
-0000033852 00000 n
-0000033956 00000 n
-0000034060 00000 n
-0000034422 00000 n
-0000034528 00000 n
-0000034634 00000 n
-0000034740 00000 n
-0000034846 00000 n
-0000034952 00000 n
-0000035058 00000 n
-0000035163 00000 n
-0000035269 00000 n
-0000035375 00000 n
-0000035480 00000 n
-0000035586 00000 n
-0000035692 00000 n
-0000035798 00000 n
-0000035903 00000 n
-0000036009 00000 n
-0000036115 00000 n
-0000036221 00000 n
-0000036327 00000 n
-0000036433 00000 n
-0000036539 00000 n
-0000036645 00000 n
-0000036751 00000 n
-0000036857 00000 n
-0000036963 00000 n
-0000037069 00000 n
-0000037175 00000 n
-0000037281 00000 n
-0000037387 00000 n
-0000037493 00000 n
-0000037599 00000 n
-0000037704 00000 n
-0000037810 00000 n
-0000037916 00000 n
-0000038022 00000 n
-0000038128 00000 n
-0000038234 00000 n
-0000038340 00000 n
-0000038446 00000 n
-0000038552 00000 n
-0000038659 00000 n
-0000038766 00000 n
-0000038872 00000 n
-0000038977 00000 n
-0000039082 00000 n
-0000039452 00000 n
-0000039559 00000 n
-0000039665 00000 n
-0000039772 00000 n
-0000039879 00000 n
-0000039986 00000 n
-0000040093 00000 n
-0000040200 00000 n
-0000040307 00000 n
-0000040414 00000 n
-0000040521 00000 n
-0000040627 00000 n
-0000040734 00000 n
-0000040841 00000 n
-0000040948 00000 n
-0000041055 00000 n
-0000041162 00000 n
-0000041269 00000 n
-0000041376 00000 n
-0000041483 00000 n
-0000041590 00000 n
-0000041697 00000 n
-0000041804 00000 n
-0000041911 00000 n
-0000042017 00000 n
+0000017277 00000 n
+0000017333 00000 n
+0000017420 00000 n
+0000017489 00000 n
+0000017576 00000 n
+0000017627 00000 n
+0000017714 00000 n
+0000017801 00000 n
+0000017888 00000 n
+0000017944 00000 n
+0000018031 00000 n
+0000018080 00000 n
+0000018167 00000 n
+0000018233 00000 n
+0000018285 00000 n
+0000018372 00000 n
+0000018427 00000 n
+0000018514 00000 n
+0000018561 00000 n
+0000018648 00000 n
+0000018695 00000 n
+0000018782 00000 n
+0000018832 00000 n
+0000018872 00000 n
+0000018959 00000 n
+0000019002 00000 n
+0000019089 00000 n
+0000019133 00000 n
+0000019220 00000 n
+0000019263 00000 n
+0000019350 00000 n
+0000019393 00000 n
+0000019480 00000 n
+0000019521 00000 n
+0000019608 00000 n
+0000019655 00000 n
+0000019742 00000 n
+0000019816 00000 n
+0000019863 00000 n
+0000019949 00000 n
+0000019975 00000 n
+0000020027 00000 n
+0000020113 00000 n
+0000020139 00000 n
+0000020193 00000 n
+0000020280 00000 n
+0000020306 00000 n
+0000020368 00000 n
+0000020455 00000 n
+0000020481 00000 n
+0000020530 00000 n
+0000020617 00000 n
+0000020643 00000 n
+0000020690 00000 n
+0000020777 00000 n
+0000020826 00000 n
+0000020913 00000 n
+0000020956 00000 n
+0000021043 00000 n
+0000021086 00000 n
+0000021172 00000 n
+0000021221 00000 n
+0000021306 00000 n
+0000021355 00000 n
+0000021440 00000 n
+0000021506 00000 n
+0000021554 00000 n
+0000021641 00000 n
+0000021687 00000 n
+0000021774 00000 n
+0000021808 00000 n
+0000021887 00000 n
+0000021974 00000 n
+0000022056 00000 n
+0000022142 00000 n
+0000022217 00000 n
+0000022304 00000 n
+0000022377 00000 n
+0000022464 00000 n
+0000022514 00000 n
+0000022592 00000 n
+0000022679 00000 n
+0000022705 00000 n
+0000022768 00000 n
+0000022855 00000 n
+0000022918 00000 n
+0000023005 00000 n
+0000023059 00000 n
+0000023146 00000 n
+0000023188 00000 n
+0000023229 00000 n
+0000023316 00000 n
+0000023342 00000 n
+0000023447 00000 n
+0000023553 00000 n
+0000023659 00000 n
+0000023765 00000 n
+0000023871 00000 n
+0000023977 00000 n
+0000024083 00000 n
+0000024189 00000 n
+0000024295 00000 n
+0000024401 00000 n
+0000024507 00000 n
+0000024613 00000 n
+0000024719 00000 n
+0000024825 00000 n
+0000024931 00000 n
+0000025037 00000 n
+0000025143 00000 n
+0000025249 00000 n
+0000025355 00000 n
+0000025461 00000 n
+0000025566 00000 n
+0000025672 00000 n
+0000025778 00000 n
+0000025884 00000 n
+0000025990 00000 n
+0000026096 00000 n
+0000026202 00000 n
+0000026308 00000 n
+0000026414 00000 n
+0000026520 00000 n
+0000026626 00000 n
+0000026732 00000 n
+0000026838 00000 n
+0000026944 00000 n
+0000027050 00000 n
+0000027156 00000 n
+0000027262 00000 n
+0000027368 00000 n
+0000027474 00000 n
+0000027579 00000 n
+0000027685 00000 n
+0000027791 00000 n
+0000027897 00000 n
+0000028000 00000 n
+0000028104 00000 n
+0000028482 00000 n
+0000028588 00000 n
+0000028693 00000 n
+0000028799 00000 n
+0000028905 00000 n
+0000029011 00000 n
+0000029117 00000 n
+0000029223 00000 n
+0000029329 00000 n
+0000029435 00000 n
+0000029541 00000 n
+0000029647 00000 n
+0000029752 00000 n
+0000029858 00000 n
+0000029964 00000 n
+0000030070 00000 n
+0000030176 00000 n
+0000030282 00000 n
+0000030388 00000 n
+0000030494 00000 n
+0000030600 00000 n
+0000030706 00000 n
+0000030812 00000 n
+0000030918 00000 n
+0000031024 00000 n
+0000031130 00000 n
+0000031235 00000 n
+0000031341 00000 n
+0000031447 00000 n
+0000031553 00000 n
+0000031658 00000 n
+0000031764 00000 n
+0000031870 00000 n
+0000031976 00000 n
+0000032082 00000 n
+0000032188 00000 n
+0000032294 00000 n
+0000032400 00000 n
+0000032506 00000 n
+0000032612 00000 n
+0000032718 00000 n
+0000032824 00000 n
+0000032929 00000 n
+0000033033 00000 n
+0000033137 00000 n
+0000033507 00000 n
+0000033612 00000 n
+0000033718 00000 n
+0000033824 00000 n
+0000033930 00000 n
+0000034036 00000 n
+0000034142 00000 n
+0000034248 00000 n
+0000034354 00000 n
+0000034460 00000 n
+0000034565 00000 n
+0000034671 00000 n
+0000034777 00000 n
+0000034883 00000 n
+0000034989 00000 n
+0000035095 00000 n
+0000035201 00000 n
+0000035307 00000 n
+0000035413 00000 n
+0000035519 00000 n
+0000035625 00000 n
+0000035731 00000 n
+0000035837 00000 n
+0000035942 00000 n
+0000036048 00000 n
+0000036154 00000 n
+0000036260 00000 n
+0000036366 00000 n
+0000036472 00000 n
+0000036578 00000 n
+0000036684 00000 n
+0000036790 00000 n
+0000036896 00000 n
+0000037002 00000 n
+0000037108 00000 n
+0000037214 00000 n
+0000037320 00000 n
+0000037426 00000 n
+0000037532 00000 n
+0000037638 00000 n
+0000037743 00000 n
+0000037849 00000 n
+0000037955 00000 n
+0000038060 00000 n
+0000038164 00000 n
+0000038268 00000 n
+0000038646 00000 n
+0000038751 00000 n
+0000038857 00000 n
+0000038963 00000 n
+0000039069 00000 n
+0000039175 00000 n
+0000039279 00000 n
+0000039345 00000 n
+0000039379 00000 n
+0000039413 00000 n
+0000042026 00000 n
+0000042075 00000 n
0000042124 00000 n
-0000042231 00000 n
-0000042338 00000 n
-0000042445 00000 n
-0000042552 00000 n
-0000042659 00000 n
-0000042766 00000 n
-0000042873 00000 n
-0000042980 00000 n
-0000043087 00000 n
-0000043194 00000 n
-0000043301 00000 n
-0000043407 00000 n
-0000043514 00000 n
-0000043621 00000 n
-0000043728 00000 n
-0000043835 00000 n
-0000043941 00000 n
-0000044046 00000 n
-0000044151 00000 n
-0000044521 00000 n
-0000044628 00000 n
-0000044735 00000 n
-0000044842 00000 n
-0000044949 00000 n
-0000045056 00000 n
-0000045163 00000 n
-0000045270 00000 n
-0000045377 00000 n
-0000045484 00000 n
-0000045591 00000 n
-0000045698 00000 n
-0000045805 00000 n
-0000045912 00000 n
-0000046018 00000 n
-0000046125 00000 n
-0000046232 00000 n
-0000046339 00000 n
-0000046446 00000 n
-0000046553 00000 n
-0000046659 00000 n
-0000046766 00000 n
-0000046873 00000 n
-0000046980 00000 n
-0000047087 00000 n
-0000047193 00000 n
-0000047300 00000 n
-0000047407 00000 n
+0000042173 00000 n
+0000042222 00000 n
+0000042271 00000 n
+0000042320 00000 n
+0000042369 00000 n
+0000042418 00000 n
+0000042467 00000 n
+0000042516 00000 n
+0000042565 00000 n
+0000042614 00000 n
+0000042663 00000 n
+0000042712 00000 n
+0000042761 00000 n
+0000042810 00000 n
+0000042859 00000 n
+0000042908 00000 n
+0000042957 00000 n
+0000043006 00000 n
+0000043055 00000 n
+0000043104 00000 n
+0000043153 00000 n
+0000043202 00000 n
+0000043251 00000 n
+0000043300 00000 n
+0000043349 00000 n
+0000043398 00000 n
+0000043447 00000 n
+0000043496 00000 n
+0000043545 00000 n
+0000043594 00000 n
+0000043643 00000 n
+0000043692 00000 n
+0000043741 00000 n
+0000043790 00000 n
+0000043839 00000 n
+0000043888 00000 n
+0000043937 00000 n
+0000043986 00000 n
+0000044035 00000 n
+0000044084 00000 n
+0000044133 00000 n
+0000044182 00000 n
+0000044231 00000 n
+0000044280 00000 n
+0000044329 00000 n
+0000044378 00000 n
+0000044427 00000 n
+0000044476 00000 n
+0000044525 00000 n
+0000044574 00000 n
+0000044623 00000 n
+0000044672 00000 n
+0000044721 00000 n
+0000044770 00000 n
+0000044819 00000 n
+0000044868 00000 n
+0000044917 00000 n
+0000044966 00000 n
+0000045015 00000 n
+0000045064 00000 n
+0000045113 00000 n
+0000045162 00000 n
+0000045211 00000 n
+0000045260 00000 n
+0000045309 00000 n
+0000045358 00000 n
+0000045407 00000 n
+0000045456 00000 n
+0000045505 00000 n
+0000045554 00000 n
+0000045603 00000 n
+0000045652 00000 n
+0000045701 00000 n
+0000045750 00000 n
+0000045799 00000 n
+0000045848 00000 n
+0000045897 00000 n
+0000045946 00000 n
+0000045995 00000 n
+0000046044 00000 n
+0000046093 00000 n
+0000046142 00000 n
+0000046191 00000 n
+0000046240 00000 n
+0000046289 00000 n
+0000046338 00000 n
+0000046387 00000 n
+0000046436 00000 n
+0000046485 00000 n
+0000046534 00000 n
+0000046583 00000 n
+0000046632 00000 n
+0000046681 00000 n
+0000046730 00000 n
+0000046779 00000 n
+0000046828 00000 n
+0000046877 00000 n
+0000046926 00000 n
+0000046975 00000 n
+0000047024 00000 n
+0000047073 00000 n
+0000047122 00000 n
+0000047171 00000 n
+0000047220 00000 n
+0000047269 00000 n
+0000047318 00000 n
+0000047367 00000 n
+0000047416 00000 n
+0000047465 00000 n
0000047514 00000 n
-0000047621 00000 n
-0000047728 00000 n
-0000047835 00000 n
-0000047940 00000 n
-0000048214 00000 n
-0000048248 00000 n
-0000048282 00000 n
-0000052100 00000 n
-0000052149 00000 n
-0000052198 00000 n
-0000052247 00000 n
-0000052296 00000 n
-0000052345 00000 n
-0000052394 00000 n
-0000052443 00000 n
-0000052492 00000 n
-0000052541 00000 n
-0000052590 00000 n
-0000052639 00000 n
-0000052688 00000 n
-0000052737 00000 n
-0000052786 00000 n
-0000052835 00000 n
-0000052884 00000 n
-0000052933 00000 n
-0000052982 00000 n
-0000053031 00000 n
-0000053080 00000 n
-0000053129 00000 n
-0000053178 00000 n
-0000053227 00000 n
-0000053276 00000 n
-0000053325 00000 n
-0000053374 00000 n
-0000053423 00000 n
-0000053472 00000 n
-0000053521 00000 n
-0000053570 00000 n
-0000053619 00000 n
-0000053668 00000 n
-0000053717 00000 n
-0000053766 00000 n
-0000053815 00000 n
-0000053864 00000 n
-0000053913 00000 n
-0000053962 00000 n
-0000054011 00000 n
-0000054060 00000 n
-0000054109 00000 n
-0000054158 00000 n
-0000054207 00000 n
-0000054256 00000 n
-0000054305 00000 n
-0000054354 00000 n
-0000054403 00000 n
-0000054452 00000 n
-0000054501 00000 n
-0000054550 00000 n
-0000054599 00000 n
-0000054648 00000 n
-0000054697 00000 n
-0000054746 00000 n
-0000054795 00000 n
-0000054844 00000 n
-0000054893 00000 n
-0000054942 00000 n
-0000054991 00000 n
-0000055040 00000 n
-0000055089 00000 n
-0000055138 00000 n
-0000055187 00000 n
-0000055236 00000 n
-0000055285 00000 n
-0000055335 00000 n
-0000055384 00000 n
-0000055433 00000 n
-0000055483 00000 n
-0000055532 00000 n
-0000055581 00000 n
-0000055631 00000 n
-0000055681 00000 n
-0000055731 00000 n
-0000055781 00000 n
-0000055831 00000 n
-0000055881 00000 n
-0000055931 00000 n
-0000055981 00000 n
-0000056030 00000 n
-0000056080 00000 n
-0000056130 00000 n
-0000056180 00000 n
-0000056229 00000 n
-0000056279 00000 n
-0000056329 00000 n
-0000056379 00000 n
-0000056429 00000 n
-0000056479 00000 n
-0000056529 00000 n
-0000056579 00000 n
-0000056629 00000 n
-0000056679 00000 n
-0000056729 00000 n
-0000056778 00000 n
-0000056827 00000 n
-0000056877 00000 n
-0000056927 00000 n
-0000056977 00000 n
-0000057027 00000 n
-0000057077 00000 n
-0000057126 00000 n
-0000057176 00000 n
-0000057226 00000 n
-0000057276 00000 n
-0000057325 00000 n
-0000057375 00000 n
-0000057425 00000 n
-0000057475 00000 n
-0000057525 00000 n
-0000057575 00000 n
-0000057625 00000 n
-0000057675 00000 n
-0000057725 00000 n
-0000057775 00000 n
-0000057824 00000 n
-0000057874 00000 n
-0000057924 00000 n
-0000057974 00000 n
-0000058024 00000 n
-0000058074 00000 n
-0000058123 00000 n
-0000058173 00000 n
-0000058223 00000 n
-0000058273 00000 n
-0000058323 00000 n
-0000058373 00000 n
-0000058423 00000 n
-0000058473 00000 n
-0000058523 00000 n
-0000058573 00000 n
-0000058622 00000 n
-0000058672 00000 n
-0000058722 00000 n
-0000058772 00000 n
-0000058822 00000 n
-0000058872 00000 n
-0000058922 00000 n
-0000058972 00000 n
-0000059021 00000 n
-0000059071 00000 n
-0000059121 00000 n
-0000059171 00000 n
-0000059221 00000 n
-0000059270 00000 n
-0000059320 00000 n
-0000059370 00000 n
-0000059420 00000 n
-0000059470 00000 n
-0000059520 00000 n
-0000059570 00000 n
-0000059620 00000 n
-0000059670 00000 n
-0000059720 00000 n
-0000059770 00000 n
-0000059820 00000 n
-0000059870 00000 n
-0000059920 00000 n
-0000059970 00000 n
-0000060020 00000 n
-0000060070 00000 n
-0000060119 00000 n
-0000060168 00000 n
-0000060217 00000 n
-0000060266 00000 n
-0000060315 00000 n
-0000060364 00000 n
-0000060413 00000 n
-0000060462 00000 n
-0000060511 00000 n
-0000060560 00000 n
-0000060609 00000 n
-0000060658 00000 n
-0000060707 00000 n
-0000060756 00000 n
-0000060805 00000 n
-0000060854 00000 n
-0000060903 00000 n
-0000060952 00000 n
-0000061001 00000 n
-0000061050 00000 n
-0000061099 00000 n
-0000061148 00000 n
-0000061197 00000 n
-0000061246 00000 n
-0000061295 00000 n
-0000061344 00000 n
-0000061393 00000 n
-0000061442 00000 n
-0000061491 00000 n
-0000061540 00000 n
-0000061589 00000 n
-0000061638 00000 n
-0000061687 00000 n
-0000061736 00000 n
-0000061785 00000 n
-0000061834 00000 n
-0000061883 00000 n
-0000061932 00000 n
-0000061981 00000 n
-0000062030 00000 n
-0000062079 00000 n
-0000062128 00000 n
-0000062177 00000 n
-0000062226 00000 n
-0000062275 00000 n
-0000062324 00000 n
-0000062373 00000 n
-0000062422 00000 n
-0000062471 00000 n
-0000062520 00000 n
-0000062569 00000 n
-0000062618 00000 n
-0000062667 00000 n
-0000062717 00000 n
-0000062767 00000 n
-0000062816 00000 n
-0000062865 00000 n
-0000062915 00000 n
-0000062964 00000 n
-0000063013 00000 n
-0000063062 00000 n
-0000063111 00000 n
-0000063161 00000 n
-0000063210 00000 n
-0000063259 00000 n
-0000063308 00000 n
-0000063358 00000 n
-0000063408 00000 n
-0000063457 00000 n
-0000063506 00000 n
-0000063555 00000 n
-0000063605 00000 n
-0000063654 00000 n
-0000063703 00000 n
-0000064784 00000 n
-0000064940 00000 n
-0000065663 00000 n
-0000065684 00000 n
-0000065858 00000 n
-0000067020 00000 n
-0000067042 00000 n
-0000067193 00000 n
-0000068699 00000 n
-0000068721 00000 n
-0000068881 00000 n
-0000070317 00000 n
-0000070339 00000 n
-0000070517 00000 n
-0000071777 00000 n
-0000071799 00000 n
-0000071941 00000 n
-0000073517 00000 n
-0000073539 00000 n
-0000073672 00000 n
-0000075466 00000 n
-0000075488 00000 n
-0000075630 00000 n
-0000077099 00000 n
-0000077121 00000 n
-0000077263 00000 n
-0000078935 00000 n
-0000078957 00000 n
-0000079099 00000 n
-0000080639 00000 n
-0000080661 00000 n
-0000080803 00000 n
-0000082401 00000 n
-0000082423 00000 n
-0000082565 00000 n
-0000084245 00000 n
-0000084267 00000 n
-0000084414 00000 n
-0000084930 00000 n
-0000084951 00000 n
-0000085112 00000 n
-0000086395 00000 n
-0000086417 00000 n
-0000086578 00000 n
-0000088333 00000 n
-0000088355 00000 n
-0000088515 00000 n
-0000090160 00000 n
-0000090182 00000 n
-0000090324 00000 n
-0000092387 00000 n
-0000092409 00000 n
-0000092551 00000 n
-0000094363 00000 n
-0000094385 00000 n
-0000094527 00000 n
-0000096251 00000 n
-0000096273 00000 n
-0000096424 00000 n
-0000098191 00000 n
-0000098213 00000 n
-0000098388 00000 n
-0000100481 00000 n
-0000100503 00000 n
-0000100663 00000 n
-0000102259 00000 n
-0000102281 00000 n
-0000102456 00000 n
-0000103950 00000 n
-0000103972 00000 n
-0000104124 00000 n
-0000104931 00000 n
-0000104952 00000 n
-0000105103 00000 n
-0000106741 00000 n
-0000106763 00000 n
-0000106928 00000 n
-0000108700 00000 n
-0000108722 00000 n
-0000108887 00000 n
-0000109780 00000 n
-0000109801 00000 n
-0000109975 00000 n
-0000111580 00000 n
-0000111602 00000 n
-0000111745 00000 n
-0000112503 00000 n
-0000112524 00000 n
-0000112707 00000 n
-0000114575 00000 n
-0000114597 00000 n
-0000114766 00000 n
-0000116619 00000 n
-0000116641 00000 n
-0000116801 00000 n
-0000118485 00000 n
-0000118507 00000 n
-0000118680 00000 n
-0000120408 00000 n
-0000120430 00000 n
-0000120581 00000 n
-0000121505 00000 n
-0000121526 00000 n
-0000121710 00000 n
-0000123534 00000 n
-0000123556 00000 n
-0000123730 00000 n
-0000125902 00000 n
-0000125924 00000 n
-0000126117 00000 n
-0000128044 00000 n
-0000128066 00000 n
-0000128251 00000 n
-0000130161 00000 n
-0000130183 00000 n
-0000130359 00000 n
-0000132161 00000 n
-0000132183 00000 n
-0000132353 00000 n
-0000133950 00000 n
-0000133972 00000 n
-0000134157 00000 n
-0000135633 00000 n
-0000135655 00000 n
-0000135797 00000 n
-0000137312 00000 n
-0000137334 00000 n
-0000137476 00000 n
-0000138868 00000 n
-0000138890 00000 n
-0000139032 00000 n
-0000140686 00000 n
-0000140708 00000 n
-0000140850 00000 n
-0000142427 00000 n
-0000142449 00000 n
-0000142582 00000 n
-0000142929 00000 n
-0000142950 00000 n
-0000143116 00000 n
-0000144984 00000 n
-0000145006 00000 n
-0000145129 00000 n
-0000146353 00000 n
-0000146375 00000 n
-0000146568 00000 n
-0000148139 00000 n
-0000148161 00000 n
-0000148336 00000 n
-0000150118 00000 n
-0000150140 00000 n
-0000150296 00000 n
-0000151857 00000 n
-0000151879 00000 n
-0000152031 00000 n
-0000153772 00000 n
-0000153794 00000 n
-0000153936 00000 n
-0000155698 00000 n
-0000155720 00000 n
-0000155871 00000 n
-0000157762 00000 n
-0000157784 00000 n
-0000157941 00000 n
-0000159778 00000 n
-0000159800 00000 n
-0000159994 00000 n
-0000162017 00000 n
-0000162039 00000 n
-0000162214 00000 n
-0000163688 00000 n
-0000163710 00000 n
-0000163885 00000 n
-0000165348 00000 n
-0000165370 00000 n
-0000165539 00000 n
-0000166852 00000 n
-0000166874 00000 n
-0000167016 00000 n
-0000168052 00000 n
-0000168073 00000 n
-0000168224 00000 n
-0000169435 00000 n
-0000169457 00000 n
-0000169608 00000 n
-0000171084 00000 n
-0000171106 00000 n
-0000171248 00000 n
-0000172297 00000 n
-0000172318 00000 n
-0000172470 00000 n
-0000173781 00000 n
-0000173803 00000 n
-0000173988 00000 n
-0000175841 00000 n
-0000175863 00000 n
-0000176029 00000 n
-0000177678 00000 n
-0000177700 00000 n
-0000177885 00000 n
-0000179825 00000 n
-0000179847 00000 n
-0000180031 00000 n
-0000181789 00000 n
-0000181811 00000 n
-0000181982 00000 n
-0000183590 00000 n
-0000183613 00000 n
-0000183784 00000 n
-0000185659 00000 n
-0000185682 00000 n
-0000185869 00000 n
-0000187735 00000 n
-0000187758 00000 n
-0000187936 00000 n
-0000190028 00000 n
-0000190051 00000 n
-0000190228 00000 n
-0000192172 00000 n
-0000192195 00000 n
-0000192373 00000 n
-0000194691 00000 n
-0000194714 00000 n
-0000194868 00000 n
-0000196852 00000 n
-0000196875 00000 n
-0000197037 00000 n
-0000198907 00000 n
-0000198930 00000 n
-0000199083 00000 n
-0000200837 00000 n
-0000200860 00000 n
-0000200994 00000 n
-0000202869 00000 n
-0000202892 00000 n
-0000203036 00000 n
-0000205111 00000 n
-0000205134 00000 n
-0000205287 00000 n
-0000207083 00000 n
-0000207106 00000 n
-0000207240 00000 n
-0000209036 00000 n
-0000209059 00000 n
-0000209184 00000 n
-0000209640 00000 n
-0000209662 00000 n
-0000209821 00000 n
-0000211457 00000 n
-0000211480 00000 n
-0000211634 00000 n
-0000213295 00000 n
-0000213318 00000 n
-0000213462 00000 n
-0000214348 00000 n
-0000214370 00000 n
-0000214557 00000 n
-0000216715 00000 n
-0000216738 00000 n
-0000216916 00000 n
-0000219103 00000 n
-0000219126 00000 n
-0000219279 00000 n
-0000220382 00000 n
-0000220405 00000 n
-0000220583 00000 n
-0000222083 00000 n
-0000222106 00000 n
-0000222293 00000 n
-0000224145 00000 n
-0000224168 00000 n
-0000224355 00000 n
-0000226264 00000 n
-0000226287 00000 n
-0000226446 00000 n
-0000227379 00000 n
-0000227401 00000 n
-0000227536 00000 n
-0000229072 00000 n
-0000229095 00000 n
-0000229230 00000 n
-0000231029 00000 n
-0000231052 00000 n
-0000231186 00000 n
-0000232882 00000 n
-0000232905 00000 n
-0000233039 00000 n
-0000234377 00000 n
-0000234400 00000 n
-0000234553 00000 n
-0000236145 00000 n
-0000236168 00000 n
-0000236321 00000 n
-0000237947 00000 n
-0000237970 00000 n
-0000238123 00000 n
-0000239419 00000 n
-0000239442 00000 n
-0000239577 00000 n
-0000241225 00000 n
-0000241248 00000 n
-0000241383 00000 n
-0000242361 00000 n
-0000242383 00000 n
-0000242527 00000 n
-0000244136 00000 n
-0000244159 00000 n
-0000244303 00000 n
-0000245787 00000 n
-0000245810 00000 n
-0000245945 00000 n
-0000247608 00000 n
-0000247631 00000 n
-0000247766 00000 n
-0000249027 00000 n
-0000249050 00000 n
-0000249185 00000 n
-0000250699 00000 n
-0000250722 00000 n
-0000250857 00000 n
-0000252634 00000 n
-0000252657 00000 n
-0000252782 00000 n
-0000253160 00000 n
-0000253182 00000 n
-0000253351 00000 n
-0000255023 00000 n
-0000255046 00000 n
-0000255205 00000 n
-0000256396 00000 n
-0000256419 00000 n
-0000256578 00000 n
-0000258133 00000 n
-0000258156 00000 n
-0000258308 00000 n
-0000259043 00000 n
-0000259065 00000 n
-0000259233 00000 n
-0000260973 00000 n
-0000260996 00000 n
-0000261149 00000 n
-0000262864 00000 n
-0000262887 00000 n
-0000263046 00000 n
-0000263409 00000 n
-0000263431 00000 n
-0000263590 00000 n
-0000268048 00000 n
-0000268071 00000 n
-0000268230 00000 n
-0000273247 00000 n
-0000273270 00000 n
-0000273429 00000 n
-0000278013 00000 n
-0000278036 00000 n
-0000278195 00000 n
-0000283045 00000 n
-0000283068 00000 n
-0000283227 00000 n
-0000286418 00000 n
-0000286441 00000 n
-0000286500 00000 n
-0000286609 00000 n
-0000286793 00000 n
-0000286915 00000 n
-0000287054 00000 n
-0000287194 00000 n
-0000287346 00000 n
-0000287500 00000 n
-0000287644 00000 n
-0000287789 00000 n
-0000287946 00000 n
-0000288112 00000 n
-0000288265 00000 n
-0000288457 00000 n
-0000288594 00000 n
-0000288726 00000 n
-0000288848 00000 n
-0000288988 00000 n
-0000289134 00000 n
-0000289254 00000 n
-0000289370 00000 n
-0000289553 00000 n
-0000289661 00000 n
-0000289782 00000 n
-0000289897 00000 n
-0000290015 00000 n
-0000290133 00000 n
-0000290251 00000 n
-0000290369 00000 n
-0000290487 00000 n
-0000290605 00000 n
-0000290723 00000 n
-0000290841 00000 n
-0000290959 00000 n
-0000291079 00000 n
-0000291199 00000 n
-0000291317 00000 n
-0000291514 00000 n
-0000291616 00000 n
-0000291768 00000 n
-0000291890 00000 n
-0000292018 00000 n
-0000292144 00000 n
-0000292274 00000 n
-0000292436 00000 n
-0000292570 00000 n
-0000292698 00000 n
-0000292820 00000 n
-0000292942 00000 n
-0000293065 00000 n
-0000293259 00000 n
-0000293449 00000 n
-0000293606 00000 n
-0000293773 00000 n
-0000293928 00000 n
-0000294035 00000 n
-0000294258 00000 n
-0000294367 00000 n
-0000294503 00000 n
-0000294628 00000 n
-0000294839 00000 n
-0000294947 00000 n
-0000295050 00000 n
-0000295260 00000 n
-0000295424 00000 n
-0000295576 00000 n
-0000295708 00000 n
-0000295855 00000 n
-0000295983 00000 n
-0000296116 00000 n
-0000296265 00000 n
-0000296434 00000 n
-0000296589 00000 n
-0000296775 00000 n
-0000296883 00000 n
-0000297006 00000 n
-0000297135 00000 n
-0000297284 00000 n
-0000297430 00000 n
-0000297584 00000 n
-0000297719 00000 n
-0000297849 00000 n
-0000297978 00000 n
-0000298122 00000 n
-0000298253 00000 n
-0000298388 00000 n
-0000298522 00000 n
-0000298703 00000 n
-0000298811 00000 n
-0000298947 00000 n
-0000299081 00000 n
-0000299228 00000 n
-0000299357 00000 n
-0000299491 00000 n
-0000299623 00000 n
-0000299750 00000 n
-0000299860 00000 n
-0000300029 00000 n
-0000300137 00000 n
-0000300277 00000 n
-0000300462 00000 n
-0000300594 00000 n
-0000300735 00000 n
-0000300874 00000 n
-0000301086 00000 n
-0000301191 00000 n
-0000301314 00000 n
-0000301446 00000 n
-0000301570 00000 n
-0000301698 00000 n
-0000301843 00000 n
-0000301975 00000 n
-0000302120 00000 n
-0000302261 00000 n
-0000302388 00000 n
-0000302529 00000 n
-0000302654 00000 n
-0000302779 00000 n
-0000302910 00000 n
-0000303032 00000 n
-0000303139 00000 n
-0000303352 00000 n
-0000303469 00000 n
-0000303590 00000 n
-0000303740 00000 n
-0000303916 00000 n
-0000304070 00000 n
-0000304230 00000 n
-0000304375 00000 n
-0000304512 00000 n
-0000304652 00000 n
-0000304790 00000 n
-0000304934 00000 n
-0000305090 00000 n
-0000305264 00000 n
-0000305416 00000 n
-0000305648 00000 n
-0000305766 00000 n
-0000305888 00000 n
-0000306050 00000 n
-0000306214 00000 n
-0000306351 00000 n
-0000306503 00000 n
-0000306643 00000 n
-0000306781 00000 n
-0000307007 00000 n
-0000307112 00000 n
-0000307236 00000 n
-0000307370 00000 n
-0000307534 00000 n
-0000307673 00000 n
-0000307809 00000 n
-0000307940 00000 n
-0000308082 00000 n
-0000308219 00000 n
-0000308373 00000 n
-0000308524 00000 n
-0000308631 00000 n
-0000308814 00000 n
-0000308932 00000 n
-0000309069 00000 n
-0000309199 00000 n
-0000309334 00000 n
-0000309485 00000 n
-0000309621 00000 n
-0000309767 00000 n
-0000309910 00000 n
-0000310052 00000 n
-0000310194 00000 n
-0000310337 00000 n
-0000310455 00000 n
-0000310636 00000 n
-0000310745 00000 n
-0000310864 00000 n
-0000310986 00000 n
-0000311114 00000 n
-0000311266 00000 n
-0000311392 00000 n
-0000311513 00000 n
-0000311633 00000 n
-0000311752 00000 n
-0000311875 00000 n
-0000311996 00000 n
-0000312118 00000 n
-0000312239 00000 n
-0000312361 00000 n
-0000312489 00000 n
-0000312616 00000 n
-0000312741 00000 n
-0000312865 00000 n
-0000312991 00000 n
-0000313100 00000 n
-0000313272 00000 n
-0000313374 00000 n
-0000313564 00000 n
-0000313759 00000 n
-0000313947 00000 n
-0000314110 00000 n
-0000314304 00000 n
-0000314414 00000 n
-0000314549 00000 n
-0000314680 00000 n
-0000314794 00000 n
-0000314964 00000 n
-0000315074 00000 n
-0000315198 00000 n
-0000315322 00000 n
-0000315449 00000 n
-0000315591 00000 n
-0000315696 00000 n
-0000315793 00000 n
+0000047563 00000 n
+0000047612 00000 n
+0000047661 00000 n
+0000047710 00000 n
+0000047759 00000 n
+0000047808 00000 n
+0000047857 00000 n
+0000047906 00000 n
+0000047955 00000 n
+0000048004 00000 n
+0000048053 00000 n
+0000048102 00000 n
+0000048151 00000 n
+0000048200 00000 n
+0000048249 00000 n
+0000048298 00000 n
+0000048347 00000 n
+0000048396 00000 n
+0000048445 00000 n
+0000048494 00000 n
+0000048543 00000 n
+0000048592 00000 n
+0000048641 00000 n
+0000048690 00000 n
+0000048739 00000 n
+0000048788 00000 n
+0000048837 00000 n
+0000048886 00000 n
+0000048935 00000 n
+0000048984 00000 n
+0000049033 00000 n
+0000049082 00000 n
+0000049131 00000 n
+0000049180 00000 n
+0000049229 00000 n
+0000049278 00000 n
+0000049327 00000 n
+0000049376 00000 n
+0000049425 00000 n
+0000049474 00000 n
+0000049523 00000 n
+0000049572 00000 n
+0000049621 00000 n
+0000049670 00000 n
+0000049719 00000 n
+0000049768 00000 n
+0000049817 00000 n
+0000049866 00000 n
+0000049915 00000 n
+0000050672 00000 n
+0000050828 00000 n
+0000051551 00000 n
+0000051572 00000 n
+0000051746 00000 n
+0000052908 00000 n
+0000052930 00000 n
+0000053081 00000 n
+0000054587 00000 n
+0000054609 00000 n
+0000054769 00000 n
+0000056205 00000 n
+0000056227 00000 n
+0000056405 00000 n
+0000057665 00000 n
+0000057687 00000 n
+0000057829 00000 n
+0000059413 00000 n
+0000059435 00000 n
+0000059568 00000 n
+0000061403 00000 n
+0000061425 00000 n
+0000061558 00000 n
+0000062081 00000 n
+0000062102 00000 n
+0000062263 00000 n
+0000063547 00000 n
+0000063569 00000 n
+0000063730 00000 n
+0000065485 00000 n
+0000065507 00000 n
+0000065667 00000 n
+0000067312 00000 n
+0000067334 00000 n
+0000067476 00000 n
+0000069546 00000 n
+0000069568 00000 n
+0000069710 00000 n
+0000071522 00000 n
+0000071544 00000 n
+0000071686 00000 n
+0000073411 00000 n
+0000073433 00000 n
+0000073584 00000 n
+0000075348 00000 n
+0000075370 00000 n
+0000075545 00000 n
+0000077652 00000 n
+0000077674 00000 n
+0000077834 00000 n
+0000079430 00000 n
+0000079452 00000 n
+0000079627 00000 n
+0000081122 00000 n
+0000081144 00000 n
+0000081296 00000 n
+0000082103 00000 n
+0000082124 00000 n
+0000082275 00000 n
+0000083913 00000 n
+0000083935 00000 n
+0000084100 00000 n
+0000085872 00000 n
+0000085894 00000 n
+0000086059 00000 n
+0000086952 00000 n
+0000086973 00000 n
+0000087147 00000 n
+0000088752 00000 n
+0000088774 00000 n
+0000088917 00000 n
+0000089675 00000 n
+0000089696 00000 n
+0000089879 00000 n
+0000091747 00000 n
+0000091769 00000 n
+0000091938 00000 n
+0000093792 00000 n
+0000093814 00000 n
+0000093974 00000 n
+0000095658 00000 n
+0000095680 00000 n
+0000095853 00000 n
+0000097582 00000 n
+0000097604 00000 n
+0000097755 00000 n
+0000098679 00000 n
+0000098700 00000 n
+0000098884 00000 n
+0000100709 00000 n
+0000100731 00000 n
+0000100905 00000 n
+0000103078 00000 n
+0000103100 00000 n
+0000103293 00000 n
+0000105220 00000 n
+0000105242 00000 n
+0000105426 00000 n
+0000107336 00000 n
+0000107358 00000 n
+0000107534 00000 n
+0000109335 00000 n
+0000109357 00000 n
+0000109527 00000 n
+0000111125 00000 n
+0000111147 00000 n
+0000111332 00000 n
+0000112808 00000 n
+0000112830 00000 n
+0000113023 00000 n
+0000114594 00000 n
+0000114616 00000 n
+0000114791 00000 n
+0000116571 00000 n
+0000116593 00000 n
+0000116749 00000 n
+0000118310 00000 n
+0000118332 00000 n
+0000118517 00000 n
+0000120369 00000 n
+0000120391 00000 n
+0000120557 00000 n
+0000122204 00000 n
+0000122226 00000 n
+0000122411 00000 n
+0000124360 00000 n
+0000124382 00000 n
+0000124566 00000 n
+0000126293 00000 n
+0000126315 00000 n
+0000126485 00000 n
+0000128090 00000 n
+0000128112 00000 n
+0000128281 00000 n
+0000130154 00000 n
+0000130176 00000 n
+0000130361 00000 n
+0000132225 00000 n
+0000132247 00000 n
+0000132423 00000 n
+0000134513 00000 n
+0000134535 00000 n
+0000134710 00000 n
+0000136650 00000 n
+0000136672 00000 n
+0000136848 00000 n
+0000139164 00000 n
+0000139186 00000 n
+0000139338 00000 n
+0000141318 00000 n
+0000141340 00000 n
+0000141500 00000 n
+0000143367 00000 n
+0000143389 00000 n
+0000143540 00000 n
+0000145292 00000 n
+0000145314 00000 n
+0000145446 00000 n
+0000147320 00000 n
+0000147342 00000 n
+0000147484 00000 n
+0000149555 00000 n
+0000149577 00000 n
+0000149728 00000 n
+0000151522 00000 n
+0000151544 00000 n
+0000151676 00000 n
+0000153469 00000 n
+0000153491 00000 n
+0000153614 00000 n
+0000154068 00000 n
+0000154089 00000 n
+0000154246 00000 n
+0000155880 00000 n
+0000155902 00000 n
+0000156054 00000 n
+0000157714 00000 n
+0000157736 00000 n
+0000157878 00000 n
+0000158761 00000 n
+0000158782 00000 n
+0000158967 00000 n
+0000161124 00000 n
+0000161146 00000 n
+0000161322 00000 n
+0000163507 00000 n
+0000163529 00000 n
+0000163680 00000 n
+0000164781 00000 n
+0000164803 00000 n
+0000164979 00000 n
+0000166479 00000 n
+0000166501 00000 n
+0000166686 00000 n
+0000168538 00000 n
+0000168560 00000 n
+0000168745 00000 n
+0000170652 00000 n
+0000170674 00000 n
+0000170831 00000 n
+0000171762 00000 n
+0000171783 00000 n
+0000171935 00000 n
+0000173676 00000 n
+0000173698 00000 n
+0000173840 00000 n
+0000175602 00000 n
+0000175624 00000 n
+0000175775 00000 n
+0000177666 00000 n
+0000177688 00000 n
+0000177845 00000 n
+0000179698 00000 n
+0000179720 00000 n
+0000179914 00000 n
+0000181974 00000 n
+0000181996 00000 n
+0000182171 00000 n
+0000183763 00000 n
+0000183785 00000 n
+0000183969 00000 n
+0000185308 00000 n
+0000185330 00000 n
+0000185490 00000 n
+0000186733 00000 n
+0000186755 00000 n
+0000186906 00000 n
+0000188362 00000 n
+0000188384 00000 n
+0000188545 00000 n
+0000190193 00000 n
+0000190215 00000 n
+0000190348 00000 n
+0000190818 00000 n
+0000190839 00000 n
+0000191006 00000 n
+0000192674 00000 n
+0000192696 00000 n
+0000192853 00000 n
+0000194041 00000 n
+0000194063 00000 n
+0000194220 00000 n
+0000195772 00000 n
+0000195794 00000 n
+0000195978 00000 n
+0000196783 00000 n
+0000196804 00000 n
+0000196961 00000 n
+0000202384 00000 n
+0000202406 00000 n
+0000202563 00000 n
+0000207857 00000 n
+0000207879 00000 n
+0000208036 00000 n
+0000213253 00000 n
+0000213275 00000 n
+0000213432 00000 n
+0000214202 00000 n
+0000214223 00000 n
+0000214280 00000 n
+0000214385 00000 n
+0000214563 00000 n
+0000214682 00000 n
+0000214817 00000 n
+0000214953 00000 n
+0000215101 00000 n
+0000215251 00000 n
+0000215391 00000 n
+0000215532 00000 n
+0000215685 00000 n
+0000215847 00000 n
+0000215996 00000 n
+0000216184 00000 n
+0000216317 00000 n
+0000216445 00000 n
+0000216563 00000 n
+0000216699 00000 n
+0000216841 00000 n
+0000216957 00000 n
+0000217083 00000 n
+0000217199 00000 n
+0000217390 00000 n
+0000217489 00000 n
+0000217637 00000 n
+0000217755 00000 n
+0000217879 00000 n
+0000218001 00000 n
+0000218127 00000 n
+0000218285 00000 n
+0000218415 00000 n
+0000218539 00000 n
+0000218657 00000 n
+0000218775 00000 n
+0000218894 00000 n
+0000219084 00000 n
+0000219270 00000 n
+0000219423 00000 n
+0000219586 00000 n
+0000219737 00000 n
+0000219841 00000 n
+0000220058 00000 n
+0000220164 00000 n
+0000220296 00000 n
+0000220418 00000 n
+0000220623 00000 n
+0000220728 00000 n
+0000220828 00000 n
+0000221032 00000 n
+0000221193 00000 n
+0000221341 00000 n
+0000221469 00000 n
+0000221612 00000 n
+0000221736 00000 n
+0000221865 00000 n
+0000222010 00000 n
+0000222175 00000 n
+0000222327 00000 n
+0000222507 00000 n
+0000222612 00000 n
+0000222731 00000 n
+0000222856 00000 n
+0000223001 00000 n
+0000223143 00000 n
+0000223293 00000 n
+0000223424 00000 n
+0000223550 00000 n
+0000223675 00000 n
+0000223815 00000 n
+0000223942 00000 n
+0000224073 00000 n
+0000224204 00000 n
+0000224382 00000 n
+0000224510 00000 n
+0000224646 00000 n
+0000224781 00000 n
+0000224987 00000 n
+0000225100 00000 n
+0000225216 00000 n
+0000225361 00000 n
+0000225532 00000 n
+0000225681 00000 n
+0000225836 00000 n
+0000225976 00000 n
+0000226108 00000 n
+0000226242 00000 n
+0000226374 00000 n
+0000226512 00000 n
+0000226662 00000 n
+0000226830 00000 n
+0000226977 00000 n
+0000227201 00000 n
+0000227314 00000 n
+0000227430 00000 n
+0000227586 00000 n
+0000227744 00000 n
+0000227875 00000 n
+0000228021 00000 n
+0000228155 00000 n
+0000228288 00000 n
+0000228509 00000 n
+0000228610 00000 n
+0000228729 00000 n
+0000228858 00000 n
+0000229017 00000 n
+0000229152 00000 n
+0000229285 00000 n
+0000229414 00000 n
+0000229554 00000 n
+0000229689 00000 n
+0000229841 00000 n
+0000229990 00000 n
+0000230095 00000 n
+0000230305 00000 n
+0000230410 00000 n
+0000230533 00000 n
+0000230665 00000 n
+0000230789 00000 n
+0000230917 00000 n
+0000231062 00000 n
+0000231194 00000 n
+0000231339 00000 n
+0000231480 00000 n
+0000231607 00000 n
+0000231748 00000 n
+0000231873 00000 n
+0000231998 00000 n
+0000232129 00000 n
+0000232251 00000 n
+0000232358 00000 n
+0000232528 00000 n
+0000232629 00000 n
+0000232818 00000 n
+0000233012 00000 n
+0000233199 00000 n
+0000233361 00000 n
+0000233553 00000 n
+0000233662 00000 n
+0000233796 00000 n
+0000233926 00000 n
+0000234039 00000 n
+0000234134 00000 n
trailer
-<</Size 1367/Root 1366 0 R/Info 1 0 R/ID[<71cc99b012ddb9744eb11230f6ad49a0><71cc99b012ddb9744eb11230f6ad49a0>]>>
+<</Size 1037/Root 1036 0 R/Info 1 0 R/ID[<59d643d3d56fb4ff0981d084417582f1><59d643d3d56fb4ff0981d084417582f1>]>>
startxref
-316009
+234349
%%EOF
diff --git a/docs/docbook/Makefile.in b/docs/docbook/Makefile.in
index 0320081876..0a21b73f6f 100644
--- a/docs/docbook/Makefile.in
+++ b/docs/docbook/Makefile.in
@@ -61,9 +61,7 @@ HOWTOSRC=projdoc/DOMAIN_MEMBER.sgml projdoc/NT_Security.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/Printing.sgml projdoc/Diagnosis.sgml \
- projdoc/security_level.sgml projdoc/Browsing.sgml projdoc/Bugs.sgml \
- projdoc/Speed.sgml
+ projdoc/Samba-BDC-HOWTO.sgml
diff --git a/docs/docbook/manpages/smb.conf.5.sgml b/docs/docbook/manpages/smb.conf.5.sgml
index 1e713147c9..641e36f57a 100644
--- a/docs/docbook/manpages/smb.conf.5.sgml
+++ b/docs/docbook/manpages/smb.conf.5.sgml
@@ -728,7 +728,7 @@
<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="SPNEGO"><parameter>use spnego</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>
@@ -1102,13 +1102,7 @@
%u</command></para>
</listitem>
</varlistentry>
-<varlistentry><term><anchor id="ADDGROUPSCRIPT">add group 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) when a new group is requested. It will expand any <parameter>%g</parameter> to the group name passed. This script is only useful for installations using the Windows NT domain administration tools.
- </ulink>
-</para></listitem>
-</varlistentry>
<varlistentry>
@@ -1916,7 +1910,6 @@
<para>This script is called when a remote client removes a user
from the server, normally using 'User Manager for Domains' or
<command>rpcclient</command>.
- </para>
<para>This script should delete the given UNIX username.
</para>
@@ -2769,10 +2762,6 @@
<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>This paramater does not accept % marcos, becouse
- many parts of the system require this value to be
- constant for correct operation</para>
<para>Default: <emphasis>specified at compile time, usually
"nobody"</emphasis></para>
@@ -3292,9 +3281,10 @@
<varlistentry>
<term><anchor id="LDAPADMINDN">ldap admin dn (G)</term>
- <listitem><para> The <parameter>ldap admin dn</parameter> defines the Distinguished
- Name (DN) name used by Samba to contact the ldap server when retreiving
- user account information. The <parameter>ldap
+ <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
@@ -3311,7 +3301,8 @@
<varlistentry>
<term><anchor id="LDAPFILTER">ldap filter (G)</term>
- <listitem><para>This parameter specifies the RFC 2254 compliant LDAP search filter.
+ <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.
@@ -3325,9 +3316,10 @@
<varlistentry>
<term><anchor id="LDAPSSL">ldap ssl (G)</term>
- <listitem><para>This option is used to define whether or not Samba should
- use SSL when connecting to the ldap server
- This is <emphasis>NOT</emphasis> related to
+ <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's previous SSL support which was enabled by specifying the
<command>--with-ssl</command> option to the <filename>configure</filename>
script.
@@ -3373,7 +3365,7 @@
<varlistentry>
- <term><anchor id="LDAPMACHINESUFFIX">ldap machine suffix (G)</term>
+ <term><anchor id="LDAPSUFFIX">ldap machine suffix (G)</term>
<listitem><para>It specifies where machines should be
added to the ldap tree.
</para>
@@ -3614,18 +3606,15 @@
<varlistentry>
<term><anchor id="LOGLEVEL">log level (G)</term>
- <listitem><para>The value of the parameter (a astring) allows
+ <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 parameter has been
- extended since 2.2.x series, now it allow to specify the debug
- level for multiple debug classes. This is to give greater
+ <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 passdb:5 auth:10 winbind:2
- </command></para></listitem>
+ <para>Example: <command>log level = 3</command></para></listitem>
</varlistentry>
@@ -6970,12 +6959,7 @@
/usr/local/smb_env_vars</command></para>
</listitem>
</varlistentry>
-<varlistentry>
-<term><anchor id="SPNEGO">use spnego (G)</term>
-<listitem><para> This variable controls controls whether samba will try to use Simple and Protected NEGOciation (as specified by rfc2478) with WindowsXP and Windows2000sp2 clients to agree upon an authentication mechanism. As of samba 3.0alpha it must be set to "no" for these clients to join a samba domain controller. It can be set to "yes" to allow samba to participate in an AD domain controlled by a Windows2000 domain controller.</para>
-<para>Default: <emphasis>use spnego = yes</emphasis></para>
-</listitem>
-</varlistentry>
+
<varlistentry>
<term><anchor id="STATCACHE">stat cache (G)</term>
@@ -7586,12 +7570,6 @@
connection is made to a Samba server. Sites may use this to record the
user connecting to a Samba share.</para>
- <para>Due to the requirements of the utmp record, we
- are required to create a unique identifier for the
- incoming user. Enabling this option creates an n^2
- algorithm to find this number. This may impede
- performance on large installations. </para>
-
<para>See also the <link linkend="UTMPDIRECTORY"><parameter>
utmp directory</parameter></link> parameter.</para>
diff --git a/docs/docbook/manpages/smbcontrol.1.sgml b/docs/docbook/manpages/smbcontrol.1.sgml
index 9a6f31b336..517e2ca41f 100644
--- a/docs/docbook/manpages/smbcontrol.1.sgml
+++ b/docs/docbook/manpages/smbcontrol.1.sgml
@@ -76,7 +76,7 @@
<constant>force-election</constant>, <constant>ping
</constant>, <constant>profile</constant>, <constant>
debuglevel</constant>, <constant>profilelevel</constant>,
- or <constant>printnotify</constant>.</para>
+ 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
@@ -119,55 +119,11 @@
setting is returned by a "profilelevel" message. This can be sent
to any smbd or nmbd destinations.</para>
- <para>The <constant>printnotify</constant> message-type sends a
+ <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 the following arguments:
-
- <variablelist>
-
- <varlistentry>
- <term>queuepause printername</term>
- <listitem><para>Send a queue pause change notify
- message to the printer specified.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>queueresume printername</term>
- <listitem><para>Send a queue resume change notify
- message for the printer specified.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>jobpause printername unixjobid</term>
- <listitem><para>Send a job pause change notify
- message for the printer and unix jobid
- specified.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>jobresume printername unixjobid</term>
- <listitem><para>Send a job resume change notify
- message for the printer and unix jobid
- specified.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term>jobdelete printername unixjobid</term>
- <listitem><para>Send a job delete change notify
- message for the printer and unix jobid
- specified.</para></listitem>
- </varlistentry>
-
- </variablelist>
-
- Note that this message only sends notification that an
- event has occured. It doesn't actually cause the
- event to happen.
-
- This message can only be sent to <constant>smbd</constant>.
- </para>
-
+ 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>
diff --git a/docs/docbook/projdoc/Samba-LDAP-HOWTO.sgml b/docs/docbook/projdoc/Samba-LDAP-HOWTO.sgml
index a66df0c767..c6c04ccab8 100644
--- a/docs/docbook/projdoc/Samba-LDAP-HOWTO.sgml
+++ b/docs/docbook/projdoc/Samba-LDAP-HOWTO.sgml
@@ -326,7 +326,7 @@ use with an LDAP directory could appear as
ldap suffix = "ou=people,dc=samba,dc=org"
# generally the default ldap search filter is ok
- # ldap filter = "(&amp;(uid=%u)(objectclass=sambaAccount))"
+ # ldap filter = "(&(uid=%u)(objectclass=sambaAccount))"
</programlisting></para>
diff --git a/docs/docbook/projdoc/Samba-PDC-HOWTO.sgml b/docs/docbook/projdoc/Samba-PDC-HOWTO.sgml
index 5b21e0a535..475b66598c 100644
--- a/docs/docbook/projdoc/Samba-PDC-HOWTO.sgml
+++ b/docs/docbook/projdoc/Samba-PDC-HOWTO.sgml
@@ -1652,7 +1652,7 @@ I think this is all bogus, but have not deleted it. (Richard Sharpe)
</warning>
<para>
-The default logon path is \\%N\%U. NT Workstation will attempt to create
+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".
diff --git a/docs/docbook/projdoc/samba-doc.sgml b/docs/docbook/projdoc/samba-doc.sgml
index 0ec9efe014..28baa7f609 100644
--- a/docs/docbook/projdoc/samba-doc.sgml
+++ b/docs/docbook/projdoc/samba-doc.sgml
@@ -13,12 +13,6 @@
<!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 Diagnosis SYSTEM "Diagnosis.sgml">
-<!ENTITY PRINTING SYSTEM "Printing.sgml">
-<!ENTITY BUGS SYSTEM "Bugs.sgml">
-<!ENTITY SECURITY-LEVEL SYSTEM "security_level.sgml">
-<!ENTITY SPEED SYSTEM "Speed.sgml">
-<!ENTITY BROWSING SYSTEM "Browsing.sgml">
<!ENTITY INDEX-FILE SYSTEM "index.sgml">
]>
@@ -37,7 +31,7 @@
<title>Abstract</title>
<para>
-<emphasis>Last Update</emphasis> : Thu Aug 15 12:48:45 CDT 2002
+<emphasis>Last Update</emphasis> : Mon Apr 1 08:47:26 CST 2002
</para>
<para>
@@ -64,24 +58,18 @@ Cheers, jerry
<!-- Chapters -->
&UNIX-INSTALL;
-&Diagnosis;
&IntegratingWithWindows;
&Samba-PAM;
&MS-Dfs-Setup;
&NT-Security;
&PRINTER-DRIVER2;
-&PRINTING;
-&SECURITY-LEVEL;
&DOMAIN-MEMBER;
-&WINBIND;
&Samba-PDC-HOWTO;
&Samba-BDC-HOWTO;
&Samba-LDAP;
-&BROWSING;
-&SPEED;
+&WINBIND;
&OS2-Client;
&CVS-Access;
-&BUGS;
<!-- Autogenerated Index -->
&INDEX-FILE;
diff --git a/docs/docbook/projdoc/winbind.sgml b/docs/docbook/projdoc/winbind.sgml
index d70c1a3679..62e065914b 100644
--- a/docs/docbook/projdoc/winbind.sgml
+++ b/docs/docbook/projdoc/winbind.sgml
@@ -23,19 +23,9 @@
<address><email>jtrostel@snapserver.com</email></address>
</affiliation>
</author>
- <author>
- <firstname>Naag</firstname><surname>Mummaneni</surname>
- <affiliation>
- <address><email>getnag@rediffmail.com</email></address>
- </affiliation>
- </author>
- <author>
- <firstname>Jelmer</firstname><surname>Vernooij</surname>
- <affiliation>
- <address><email>jelmer@nl.linux.org</email></address>
- </affiliation>
- </author>
- <pubdate>27 June 2002</pubdate>
+
+
+ <pubdate>16 Oct 2000</pubdate>
</chapterinfo>
<title>Unified Logons between Windows NT and UNIX using Winbind</title>
@@ -499,13 +489,6 @@ I also found it necessary to make the following symbolic link:
<prompt>root#</prompt> <command>ln -s /lib/libnss_winbind.so /lib/libnss_winbind.so.2</command>
</para>
-<para>And, in the case of Sun solaris:</para>
-<para>
-<prompt>root#</prompt> <command>ln -s /usr/lib/libnss_winbind.so /usr/lib/libnss_winbind.so.1</command>
-<prompt>root#</prompt> <command>ln -s /usr/lib/libnss_winbind.so /usr/lib/nss_winbind.so.1</command>
-<prompt>root#</prompt> <command>ln -s /usr/lib/libnss_winbind.so /usr/lib/nss_winbind.so.2</command>
-</para>
-
<para>
Now, as root you need to edit <filename>/etc/nsswitch.conf</filename> to
allow user and group entries to be visible from the <command>winbindd</command>
@@ -699,18 +682,14 @@ The same thing can be done for groups with the command
<sect3>
-<title>Fix the init.d startup scripts</title>
-
-<sect4>
-<title>Linux</title>
+<title>Fix the <filename>/etc/rc.d/init.d/smb</filename> startup files</title>
<para>
The <command>winbindd</command> daemon needs to start up after the
<command>smbd</command> and <command>nmbd</command> daemons are running.
-To accomplish this task, you need to modify the startup scripts of your system. They are located at <filename>/etc/init.d/smb</filename> in RedHat and
-<filename>/etc/init.d/samba</filename> in Debian.
+To accomplish this task, you need to modify the <filename>/etc/init.d/smb</filename>
script to add commands to invoke this daemon in the proper sequence. My
-startup script starts up <command>smbd</command>,
+<filename>/etc/init.d/smb</filename> file starts up <command>smbd</command>,
<command>nmbd</command>, and <command>winbindd</command> from the
<filename>/usr/local/samba/bin</filename> directory directly. The 'start'
function in the script looks like this:
@@ -765,79 +744,18 @@ stop() {
return $RETVAL
}
</programlisting></para>
-</sect4>
-
-<sect4>
-<title>Solaris</title>
-<para>On solaris, you need to modify the
-<filename>/etc/init.d/samba.server</filename> startup script. It usually
-only starts smbd and nmbd but should now start winbindd too. If you
-have samba installed in <filename>/usr/local/samba/bin</filename>,
-the file could contains something like this:
-</para>
-
-<para><programlisting>
-##
-## samba.server
-##
-
-if [ ! -d /usr/bin ]
-then # /usr not mounted
- exit
-fi
-
-killproc() { # kill the named process(es)
- pid=`/usr/bin/ps -e |
- /usr/bin/grep -w $1 |
- /usr/bin/sed -e 's/^ *//' -e 's/ .*//'`
- [ "$pid" != "" ] && kill $pid
-}
-
-# Start/stop processes required for samba server
-
-case "$1" in
-
-'start')
-#
-# Edit these lines to suit your installation (paths, workgroup, host)
-#
-echo Starting SMBD
- /usr/local/samba/bin/smbd -D -s \
- /usr/local/samba/smb.conf
-
-echo Starting NMBD
- /usr/local/samba/bin/nmbd -D -l \
- /usr/local/samba/var/log -s /usr/local/samba/smb.conf
-
-echo Starting Winbind Daemon
- /usr/local/samba/bin/winbindd
- ;;
-
-'stop')
- killproc nmbd
- killproc smbd
- killproc winbindd
- ;;
-
-*)
- echo "Usage: /etc/init.d/samba.server { start | stop }"
- ;;
-esac
-</programlisting></para>
-</sect4>
-
-<sect4>
-<title>Restarting</title>
<para>
If you restart the <command>smbd</command>, <command>nmbd</command>,
and <command>winbindd</command> daemons at this point, you
should be able to connect to the samba server as a domain member just as
if you were a local user.
</para>
-</sect4>
+
</sect3>
+
+
<sect3>
<title>Configure Winbind and PAM</title>
@@ -863,17 +781,13 @@ by invoking the command
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 my RedHat system, this was the
-<filename>/lib/security</filename> directory. On Solaris, the pam security
-modules reside in <filename>/usr/lib/security</filename>.
+<filename>/lib/security</filename> directory.
</para>
<para>
<prompt>root#</prompt> <command>cp ../samba/source/nsswitch/pam_winbind.so /lib/security</command>
</para>
-<sect4>
-<title>Linux/FreeBSD-specific PAM configuration</title>
-
<para>
The <filename>/etc/pam.d/samba</filename> file does not need to be changed. I
just left this fileas it was:
@@ -961,92 +875,6 @@ line after the <command>winbind.so</command> line to get rid of annoying
double prompts for passwords.
</para>
-</sect4>
-
-<sect4>
-<title>Solaris-specific configuration</title>
-
-<para>
-The /etc/pam.conf needs to be changed. I changed this file so that my Domain
-users can logon both locally as well as telnet.The following are the changes
-that I made.You can customize the pam.conf file as per your requirements,but
-be sure of those changes because in the worst case it will leave your system
-nearly impossible to boot.
-</para>
-
-<para><programlisting>
-#
-#ident "@(#)pam.conf 1.14 99/09/16 SMI"
-#
-# Copyright (c) 1996-1999, Sun Microsystems, Inc.
-# All Rights Reserved.
-#
-# PAM configuration
-#
-# Authentication management
-#
-login auth required /usr/lib/security/pam_winbind.so
-login auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-login auth required /usr/lib/security/$ISA/pam_dial_auth.so.1 try_first_pass
-#
-rlogin auth sufficient /usr/lib/security/pam_winbind.so
-rlogin auth sufficient /usr/lib/security/$ISA/pam_rhosts_auth.so.1
-rlogin auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-dtlogin auth sufficient /usr/lib/security/pam_winbind.so
-dtlogin auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-rsh auth required /usr/lib/security/$ISA/pam_rhosts_auth.so.1
-other auth sufficient /usr/lib/security/pam_winbind.so
-other auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-# Account management
-#
-login account sufficient /usr/lib/security/pam_winbind.so
-login account requisite /usr/lib/security/$ISA/pam_roles.so.1
-login account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-dtlogin account sufficient /usr/lib/security/pam_winbind.so
-dtlogin account requisite /usr/lib/security/$ISA/pam_roles.so.1
-dtlogin account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-other account sufficient /usr/lib/security/pam_winbind.so
-other account requisite /usr/lib/security/$ISA/pam_roles.so.1
-other account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Session management
-#
-other session required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Password management
-#
-#other password sufficient /usr/lib/security/pam_winbind.so
-other password required /usr/lib/security/$ISA/pam_unix.so.1
-dtsession auth required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Support for Kerberos V5 authentication (uncomment to use Kerberos)
-#
-#rlogin auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#login auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#dtlogin auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#other auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#dtlogin account optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other account optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other session optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other password optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-</programlisting></para>
-
-<para>
-I also added a try_first_pass line after the winbind.so line to get rid of
-annoying double prompts for passwords.
-</para>
-
-<para>
-Now restart your Samba & try connecting through your application that you
-configured in the pam.conf.
-</para>
-
-</sect4>
</sect3>
diff --git a/docs/htmldocs/Integrating-with-Windows.html b/docs/htmldocs/Integrating-with-Windows.html
index fd2bd7fdaf..7c5fe31627 100644
--- a/docs/htmldocs/Integrating-with-Windows.html
+++ b/docs/htmldocs/Integrating-with-Windows.html
@@ -191,7 +191,7 @@ CLASS="FILENAME"
> 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
+determined a protocol called ARP/RARP isused 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
@@ -414,7 +414,7 @@ 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
+just a password (known as SHARE MORE 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
@@ -444,8 +444,8 @@ NAME="AEN100"
></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
+stored the NetBIOS names and their IP addresses for all external
+machines that that the local 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
@@ -453,7 +453,7 @@ configured name resolution mechanisms.</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
+to time-out delays. ie: It's 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
@@ -660,7 +660,7 @@ 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
+(ie: 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
@@ -685,7 +685,7 @@ 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
+is held to determine which machine will be the master browser. By 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
@@ -770,8 +770,8 @@ 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
+use the mapped drive connection that has been dropped the SMB protocol
+has a mechanism by which the connection can be re-established using
a cached copy of the password.</P
><P
>When Microsoft changed the default password mode, they dropped support for
@@ -959,7 +959,7 @@ NAME="AEN196"
></H2
><P
>This mode of authentication demands that there be on the
-Unix/Linux system both a Unix style account as well as an
+Unix/Linux system both a Unix style account as well as and
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
diff --git a/docs/htmldocs/Samba-HOWTO-Collection.html b/docs/htmldocs/Samba-HOWTO-Collection.html
index ffb6939e17..5175bd4c8d 100644
--- a/docs/htmldocs/Samba-HOWTO-Collection.html
+++ b/docs/htmldocs/Samba-HOWTO-Collection.html
@@ -40,7 +40,7 @@ NAME="AEN8"
><P
><EM
>Last Update</EM
-> : Thu Aug 15 12:48:45 CDT 2002</P
+> : 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
@@ -178,147 +178,64 @@ HREF="#AEN199"
></DT
><DT
>1.10.6. <A
-HREF="#AEN208"
+HREF="#AEN209"
>Mapping Usernames</A
></DT
-></DL
-></DD
-></DL
-></DD
-><DT
->2. <A
-HREF="#DIAGNOSIS"
->Diagnosing your samba server</A
-></DT
-><DD
-><DL
-><DT
->2.1. <A
-HREF="#AEN222"
->Introduction</A
-></DT
-><DT
->2.2. <A
-HREF="#AEN227"
->Assumptions</A
-></DT
-><DT
->2.3. <A
-HREF="#AEN237"
->Tests</A
-></DT
-><DD
-><DL
-><DT
->2.3.1. <A
-HREF="#AEN239"
->Test 1</A
-></DT
-><DT
->2.3.2. <A
-HREF="#AEN245"
->Test 2</A
-></DT
-><DT
->2.3.3. <A
-HREF="#AEN251"
->Test 3</A
-></DT
-><DT
->2.3.4. <A
-HREF="#AEN266"
->Test 4</A
-></DT
-><DT
->2.3.5. <A
-HREF="#AEN271"
->Test 5</A
-></DT
-><DT
->2.3.6. <A
-HREF="#AEN277"
->Test 6</A
-></DT
-><DT
->2.3.7. <A
-HREF="#AEN285"
->Test 7</A
-></DT
-><DT
->2.3.8. <A
-HREF="#AEN311"
->Test 8</A
-></DT
-><DT
->2.3.9. <A
-HREF="#AEN328"
->Test 9</A
-></DT
-><DT
->2.3.10. <A
-HREF="#AEN333"
->Test 10</A
-></DT
><DT
->2.3.11. <A
-HREF="#AEN339"
->Test 11</A
+>1.10.7. <A
+HREF="#AEN212"
+>Other Character Sets</A
></DT
></DL
></DD
-><DT
->2.4. <A
-HREF="#AEN344"
->Still having troubles?</A
-></DT
></DL
></DD
><DT
->3. <A
+>2. <A
HREF="#INTEGRATE-MS-NETWORKS"
>Integrating MS Windows networks with Samba</A
></DT
><DD
><DL
><DT
->3.1. <A
-HREF="#AEN361"
+>2.1. <A
+HREF="#AEN226"
>Agenda</A
></DT
><DT
->3.2. <A
-HREF="#AEN383"
+>2.2. <A
+HREF="#AEN248"
>Name Resolution in a pure Unix/Linux world</A
></DT
><DD
><DL
><DT
->3.2.1. <A
-HREF="#AEN399"
+>2.2.1. <A
+HREF="#AEN264"
><TT
CLASS="FILENAME"
>/etc/hosts</TT
></A
></DT
><DT
->3.2.2. <A
-HREF="#AEN415"
+>2.2.2. <A
+HREF="#AEN280"
><TT
CLASS="FILENAME"
>/etc/resolv.conf</TT
></A
></DT
><DT
->3.2.3. <A
-HREF="#AEN426"
+>2.2.3. <A
+HREF="#AEN291"
><TT
CLASS="FILENAME"
>/etc/host.conf</TT
></A
></DT
><DT
->3.2.4. <A
-HREF="#AEN434"
+>2.2.4. <A
+HREF="#AEN299"
><TT
CLASS="FILENAME"
>/etc/nsswitch.conf</TT
@@ -327,78 +244,78 @@ CLASS="FILENAME"
></DL
></DD
><DT
->3.3. <A
-HREF="#AEN446"
+>2.3. <A
+HREF="#AEN311"
>Name resolution as used within MS Windows networking</A
></DT
><DD
><DL
><DT
->3.3.1. <A
-HREF="#AEN458"
+>2.3.1. <A
+HREF="#AEN323"
>The NetBIOS Name Cache</A
></DT
><DT
->3.3.2. <A
-HREF="#AEN463"
+>2.3.2. <A
+HREF="#AEN328"
>The LMHOSTS file</A
></DT
><DT
->3.3.3. <A
-HREF="#AEN471"
+>2.3.3. <A
+HREF="#AEN336"
>HOSTS file</A
></DT
><DT
->3.3.4. <A
-HREF="#AEN476"
+>2.3.4. <A
+HREF="#AEN341"
>DNS Lookup</A
></DT
><DT
->3.3.5. <A
-HREF="#AEN479"
+>2.3.5. <A
+HREF="#AEN344"
>WINS Lookup</A
></DT
></DL
></DD
><DT
->3.4. <A
-HREF="#AEN491"
+>2.4. <A
+HREF="#AEN356"
>How browsing functions and how to deploy stable and
dependable browsing using Samba</A
></DT
><DT
->3.5. <A
-HREF="#AEN501"
+>2.5. <A
+HREF="#AEN366"
>MS Windows security options and how to configure
Samba for seemless integration</A
></DT
><DD
><DL
><DT
->3.5.1. <A
-HREF="#AEN529"
+>2.5.1. <A
+HREF="#AEN394"
>Use MS Windows NT as an authentication server</A
></DT
><DT
->3.5.2. <A
-HREF="#AEN537"
+>2.5.2. <A
+HREF="#AEN402"
>Make Samba a member of an MS Windows NT security domain</A
></DT
><DT
->3.5.3. <A
-HREF="#AEN554"
+>2.5.3. <A
+HREF="#AEN419"
>Configure Samba as an authentication server</A
></DT
><DD
><DL
><DT
->3.5.3.1. <A
-HREF="#AEN561"
+>2.5.3.1. <A
+HREF="#AEN426"
>Users</A
></DT
><DT
->3.5.3.2. <A
-HREF="#AEN566"
+>2.5.3.2. <A
+HREF="#AEN431"
>MS Windows NT Machine Accounts</A
></DT
></DL
@@ -406,14 +323,14 @@ HREF="#AEN566"
></DL
></DD
><DT
->3.6. <A
-HREF="#AEN571"
+>2.6. <A
+HREF="#AEN436"
>Conclusions</A
></DT
></DL
></DD
><DT
->4. <A
+>3. <A
HREF="#PAM"
>Configuring PAM for distributed but centrally
managed authentication</A
@@ -421,39 +338,39 @@ managed authentication</A
><DD
><DL
><DT
->4.1. <A
-HREF="#AEN592"
+>3.1. <A
+HREF="#AEN457"
>Samba and PAM</A
></DT
><DT
->4.2. <A
-HREF="#AEN636"
+>3.2. <A
+HREF="#AEN501"
>Distributed Authentication</A
></DT
><DT
->4.3. <A
-HREF="#AEN643"
+>3.3. <A
+HREF="#AEN508"
>PAM Configuration in smb.conf</A
></DT
></DL
></DD
><DT
->5. <A
+>4. <A
HREF="#MSDFS"
>Hosting a Microsoft Distributed File System tree on Samba</A
></DT
><DD
><DL
><DT
->5.1. <A
-HREF="#AEN663"
+>4.1. <A
+HREF="#AEN528"
>Instructions</A
></DT
><DD
><DL
><DT
->5.1.1. <A
-HREF="#AEN698"
+>4.1.1. <A
+HREF="#AEN563"
>Notes</A
></DT
></DL
@@ -461,144 +378,144 @@ HREF="#AEN698"
></DL
></DD
><DT
->6. <A
+>5. <A
HREF="#UNIX-PERMISSIONS"
>UNIX Permission Bits and Windows NT Access Control Lists</A
></DT
><DD
><DL
><DT
->6.1. <A
-HREF="#AEN718"
+>5.1. <A
+HREF="#AEN583"
>Viewing and changing UNIX permissions using the NT
security dialogs</A
></DT
><DT
->6.2. <A
-HREF="#AEN727"
+>5.2. <A
+HREF="#AEN592"
>How to view file security on a Samba share</A
></DT
><DT
->6.3. <A
-HREF="#AEN738"
+>5.3. <A
+HREF="#AEN603"
>Viewing file ownership</A
></DT
><DT
->6.4. <A
-HREF="#AEN758"
+>5.4. <A
+HREF="#AEN623"
>Viewing file or directory permissions</A
></DT
><DD
><DL
><DT
->6.4.1. <A
-HREF="#AEN773"
+>5.4.1. <A
+HREF="#AEN638"
>File Permissions</A
></DT
><DT
->6.4.2. <A
-HREF="#AEN787"
+>5.4.2. <A
+HREF="#AEN652"
>Directory Permissions</A
></DT
></DL
></DD
><DT
->6.5. <A
-HREF="#AEN794"
+>5.5. <A
+HREF="#AEN659"
>Modifying file or directory permissions</A
></DT
><DT
->6.6. <A
-HREF="#AEN816"
+>5.6. <A
+HREF="#AEN681"
>Interaction with the standard Samba create mask
parameters</A
></DT
><DT
->6.7. <A
-HREF="#AEN880"
+>5.7. <A
+HREF="#AEN745"
>Interaction with the standard Samba file attribute
mapping</A
></DT
></DL
></DD
><DT
->7. <A
+>6. <A
HREF="#PRINTING"
>Printing Support in Samba 2.2.x</A
></DT
><DD
><DL
><DT
->7.1. <A
-HREF="#AEN901"
+>6.1. <A
+HREF="#AEN766"
>Introduction</A
></DT
><DT
->7.2. <A
-HREF="#AEN923"
+>6.2. <A
+HREF="#AEN788"
>Configuration</A
></DT
><DD
><DL
><DT
->7.2.1. <A
-HREF="#AEN934"
+>6.2.1. <A
+HREF="#AEN799"
>Creating [print$]</A
></DT
><DT
->7.2.2. <A
-HREF="#AEN969"
+>6.2.2. <A
+HREF="#AEN834"
>Setting Drivers for Existing Printers</A
></DT
><DT
->7.2.3. <A
-HREF="#AEN986"
+>6.2.3. <A
+HREF="#AEN851"
>Support a large number of printers</A
></DT
><DT
->7.2.4. <A
-HREF="#AEN997"
+>6.2.4. <A
+HREF="#AEN862"
>Adding New Printers via the Windows NT APW</A
></DT
><DT
->7.2.5. <A
-HREF="#AEN1022"
+>6.2.5. <A
+HREF="#AEN887"
>Samba and Printer Ports</A
></DT
></DL
></DD
><DT
->7.3. <A
-HREF="#AEN1030"
+>6.3. <A
+HREF="#AEN895"
>The Imprints Toolset</A
></DT
><DD
><DL
><DT
->7.3.1. <A
-HREF="#AEN1034"
+>6.3.1. <A
+HREF="#AEN899"
>What is Imprints?</A
></DT
><DT
->7.3.2. <A
-HREF="#AEN1044"
+>6.3.2. <A
+HREF="#AEN909"
>Creating Printer Driver Packages</A
></DT
><DT
->7.3.3. <A
-HREF="#AEN1047"
+>6.3.3. <A
+HREF="#AEN912"
>The Imprints server</A
></DT
><DT
->7.3.4. <A
-HREF="#AEN1051"
+>6.3.4. <A
+HREF="#AEN916"
>The Installation Client</A
></DT
></DL
></DD
><DT
->7.4. <A
-HREF="#AEN1073"
+>6.4. <A
+HREF="#AEN938"
><A
NAME="MIGRATION"
></A
@@ -607,360 +524,143 @@ NAME="MIGRATION"
></DL
></DD
><DT
->8. <A
-HREF="#PRINTING_DEBUG"
->Debugging Printing Problems</A
-></DT
-><DD
-><DL
-><DT
->8.1. <A
-HREF="#AEN1119"
->Introduction</A
-></DT
-><DT
->8.2. <A
-HREF="#AEN1135"
->Debugging printer problems</A
-></DT
-><DT
->8.3. <A
-HREF="#AEN1144"
->What printers do I have?</A
-></DT
-><DT
->8.4. <A
-HREF="#AEN1152"
->Setting up printcap and print servers</A
-></DT
-><DT
->8.5. <A
-HREF="#AEN1180"
->Job sent, no output</A
-></DT
-><DT
->8.6. <A
-HREF="#AEN1191"
->Job sent, strange output</A
-></DT
-><DT
->8.7. <A
-HREF="#AEN1203"
->Raw PostScript printed</A
-></DT
-><DT
->8.8. <A
-HREF="#AEN1206"
->Advanced Printing</A
-></DT
-><DT
->8.9. <A
-HREF="#AEN1209"
->Real debugging</A
-></DT
-></DL
-></DD
-><DT
->9. <A
-HREF="#SECURITY_LEVELS"
->Security levels</A
-></DT
-><DD
-><DL
-><DT
->9.1. <A
-HREF="#AEN1222"
->Introduction</A
-></DT
-><DT
->9.2. <A
-HREF="#AEN1233"
->More complete description of security levels</A
-></DT
-></DL
-></DD
-><DT
->10. <A
+>7. <A
HREF="#DOMAIN-SECURITY"
>security = domain in Samba 2.x</A
></DT
><DD
><DL
><DT
->10.1. <A
-HREF="#AEN1266"
+>7.1. <A
+HREF="#AEN992"
>Joining an NT Domain with Samba 2.2</A
></DT
><DT
->10.2. <A
-HREF="#AEN1330"
+>7.2. <A
+HREF="#AEN1056"
>Samba and Windows 2000 Domains</A
></DT
><DT
->10.3. <A
-HREF="#AEN1335"
+>7.3. <A
+HREF="#AEN1061"
>Why is this better than security = server?</A
></DT
></DL
></DD
><DT
->11. <A
-HREF="#WINBIND"
->Unified Logons between Windows NT and UNIX using Winbind</A
-></DT
-><DD
-><DL
-><DT
->11.1. <A
-HREF="#AEN1388"
->Abstract</A
-></DT
-><DT
->11.2. <A
-HREF="#AEN1392"
->Introduction</A
-></DT
-><DT
->11.3. <A
-HREF="#AEN1405"
->What Winbind Provides</A
-></DT
-><DD
-><DL
-><DT
->11.3.1. <A
-HREF="#AEN1412"
->Target Uses</A
-></DT
-></DL
-></DD
-><DT
->11.4. <A
-HREF="#AEN1416"
->How Winbind Works</A
-></DT
-><DD
-><DL
-><DT
->11.4.1. <A
-HREF="#AEN1421"
->Microsoft Remote Procedure Calls</A
-></DT
-><DT
->11.4.2. <A
-HREF="#AEN1425"
->Name Service Switch</A
-></DT
-><DT
->11.4.3. <A
-HREF="#AEN1441"
->Pluggable Authentication Modules</A
-></DT
-><DT
->11.4.4. <A
-HREF="#AEN1449"
->User and Group ID Allocation</A
-></DT
-><DT
->11.4.5. <A
-HREF="#AEN1453"
->Result Caching</A
-></DT
-></DL
-></DD
-><DT
->11.5. <A
-HREF="#AEN1456"
->Installation and Configuration</A
-></DT
-><DD
-><DL
-><DT
->11.5.1. <A
-HREF="#AEN1463"
->Introduction</A
-></DT
-><DT
->11.5.2. <A
-HREF="#AEN1476"
->Requirements</A
-></DT
-><DT
->11.5.3. <A
-HREF="#AEN1490"
->Testing Things Out</A
-></DT
-><DD
-><DL
-><DT
->11.5.3.1. <A
-HREF="#AEN1501"
->Configure and compile SAMBA</A
-></DT
-><DT
->11.5.3.2. <A
-HREF="#AEN1520"
->Configure <TT
-CLASS="FILENAME"
->nsswitch.conf</TT
-> and the
-winbind libraries</A
-></DT
-><DT
->11.5.3.3. <A
-HREF="#AEN1553"
->Configure smb.conf</A
-></DT
-><DT
->11.5.3.4. <A
-HREF="#AEN1569"
->Join the SAMBA server to the PDC domain</A
-></DT
-><DT
->11.5.3.5. <A
-HREF="#AEN1580"
->Start up the winbindd daemon and test it!</A
-></DT
-><DT
->11.5.3.6. <A
-HREF="#AEN1616"
->Fix the init.d startup scripts</A
-></DT
-><DT
->11.5.3.7. <A
-HREF="#AEN1648"
->Configure Winbind and PAM</A
-></DT
-></DL
-></DD
-></DL
-></DD
-><DT
->11.6. <A
-HREF="#AEN1705"
->Limitations</A
-></DT
-><DT
->11.7. <A
-HREF="#AEN1715"
->Conclusion</A
-></DT
-></DL
-></DD
-><DT
->12. <A
+>8. <A
HREF="#SAMBA-PDC"
>How to Configure Samba 2.2 as a Primary Domain Controller</A
></DT
><DD
><DL
><DT
->12.1. <A
-HREF="#AEN1735"
+>8.1. <A
+HREF="#AEN1094"
>Prerequisite Reading</A
></DT
><DT
->12.2. <A
-HREF="#AEN1741"
+>8.2. <A
+HREF="#AEN1100"
>Background</A
></DT
><DT
->12.3. <A
-HREF="#AEN1780"
+>8.3. <A
+HREF="#AEN1139"
>Configuring the Samba Domain Controller</A
></DT
><DT
->12.4. <A
-HREF="#AEN1823"
+>8.4. <A
+HREF="#AEN1182"
>Creating Machine Trust Accounts and Joining Clients to the
Domain</A
></DT
><DD
><DL
><DT
->12.4.1. <A
-HREF="#AEN1842"
+>8.4.1. <A
+HREF="#AEN1201"
>Manual Creation of Machine Trust Accounts</A
></DT
><DT
->12.4.2. <A
-HREF="#AEN1877"
+>8.4.2. <A
+HREF="#AEN1236"
>"On-the-Fly" Creation of Machine Trust Accounts</A
></DT
><DT
->12.4.3. <A
-HREF="#AEN1886"
+>8.4.3. <A
+HREF="#AEN1245"
>Joining the Client to the Domain</A
></DT
></DL
></DD
><DT
->12.5. <A
-HREF="#AEN1901"
+>8.5. <A
+HREF="#AEN1260"
>Common Problems and Errors</A
></DT
><DT
->12.6. <A
-HREF="#AEN1949"
+>8.6. <A
+HREF="#AEN1308"
>System Policies and Profiles</A
></DT
><DT
->12.7. <A
-HREF="#AEN1993"
+>8.7. <A
+HREF="#AEN1352"
>What other help can I get?</A
></DT
><DT
->12.8. <A
-HREF="#AEN2107"
+>8.8. <A
+HREF="#AEN1466"
>Domain Control for Windows 9x/ME</A
></DT
><DD
><DL
><DT
->12.8.1. <A
-HREF="#AEN2133"
+>8.8.1. <A
+HREF="#AEN1492"
>Configuration Instructions: Network Logons</A
></DT
><DT
->12.8.2. <A
-HREF="#AEN2152"
+>8.8.2. <A
+HREF="#AEN1511"
>Configuration Instructions: Setting up Roaming User Profiles</A
></DT
><DD
><DL
><DT
->12.8.2.1. <A
-HREF="#AEN2160"
+>8.8.2.1. <A
+HREF="#AEN1519"
>Windows NT Configuration</A
></DT
><DT
->12.8.2.2. <A
-HREF="#AEN2168"
+>8.8.2.2. <A
+HREF="#AEN1527"
>Windows 9X Configuration</A
></DT
><DT
->12.8.2.3. <A
-HREF="#AEN2176"
+>8.8.2.3. <A
+HREF="#AEN1535"
>Win9X and WinNT Configuration</A
></DT
><DT
->12.8.2.4. <A
-HREF="#AEN2183"
+>8.8.2.4. <A
+HREF="#AEN1542"
>Windows 9X Profile Setup</A
></DT
><DT
->12.8.2.5. <A
-HREF="#AEN2219"
+>8.8.2.5. <A
+HREF="#AEN1578"
>Windows NT Workstation 4.0</A
></DT
><DT
->12.8.2.6. <A
-HREF="#AEN2232"
+>8.8.2.6. <A
+HREF="#AEN1591"
>Windows NT Server</A
></DT
><DT
->12.8.2.7. <A
-HREF="#AEN2235"
+>8.8.2.7. <A
+HREF="#AEN1594"
>Sharing Profiles between W95 and NT Workstation 4.0</A
></DT
></DL
@@ -968,63 +668,63 @@ HREF="#AEN2235"
></DL
></DD
><DT
->12.9. <A
-HREF="#AEN2245"
+>8.9. <A
+HREF="#AEN1604"
>DOMAIN_CONTROL.txt : Windows NT Domain Control &#38; Samba</A
></DT
></DL
></DD
><DT
->13. <A
+>9. <A
HREF="#SAMBA-BDC"
>How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain</A
></DT
><DD
><DL
><DT
->13.1. <A
-HREF="#AEN2281"
+>9.1. <A
+HREF="#AEN1640"
>Prerequisite Reading</A
></DT
><DT
->13.2. <A
-HREF="#AEN2285"
+>9.2. <A
+HREF="#AEN1644"
>Background</A
></DT
><DT
->13.3. <A
-HREF="#AEN2293"
+>9.3. <A
+HREF="#AEN1652"
>What qualifies a Domain Controller on the network?</A
></DT
><DD
><DL
><DT
->13.3.1. <A
-HREF="#AEN2296"
+>9.3.1. <A
+HREF="#AEN1655"
>How does a Workstation find its domain controller?</A
></DT
><DT
->13.3.2. <A
-HREF="#AEN2299"
+>9.3.2. <A
+HREF="#AEN1658"
>When is the PDC needed?</A
></DT
></DL
></DD
><DT
->13.4. <A
-HREF="#AEN2302"
+>9.4. <A
+HREF="#AEN1661"
>Can Samba be a Backup Domain Controller?</A
></DT
><DT
->13.5. <A
-HREF="#AEN2306"
+>9.5. <A
+HREF="#AEN1665"
>How do I set up a Samba BDC?</A
></DT
><DD
><DL
><DT
->13.5.1. <A
-HREF="#AEN2322"
+>9.5.1. <A
+HREF="#AEN1681"
>How do I replicate the smbpasswd file?</A
></DT
></DL
@@ -1032,299 +732,260 @@ HREF="#AEN2322"
></DL
></DD
><DT
->14. <A
+>10. <A
HREF="#SAMBA-LDAP-HOWTO"
>Storing Samba's User/Machine Account information in an LDAP Directory</A
></DT
><DD
><DL
><DT
->14.1. <A
-HREF="#AEN2343"
+>10.1. <A
+HREF="#AEN1702"
>Purpose</A
></DT
><DT
->14.2. <A
-HREF="#AEN2363"
+>10.2. <A
+HREF="#AEN1722"
>Introduction</A
></DT
><DT
->14.3. <A
-HREF="#AEN2392"
+>10.3. <A
+HREF="#AEN1751"
>Supported LDAP Servers</A
></DT
><DT
->14.4. <A
-HREF="#AEN2397"
+>10.4. <A
+HREF="#AEN1756"
>Schema and Relationship to the RFC 2307 posixAccount</A
></DT
><DT
->14.5. <A
-HREF="#AEN2409"
+>10.5. <A
+HREF="#AEN1768"
>Configuring Samba with LDAP</A
></DT
><DD
><DL
><DT
->14.5.1. <A
-HREF="#AEN2411"
+>10.5.1. <A
+HREF="#AEN1770"
>OpenLDAP configuration</A
></DT
><DT
->14.5.2. <A
-HREF="#AEN2428"
+>10.5.2. <A
+HREF="#AEN1787"
>Configuring Samba</A
></DT
></DL
></DD
><DT
->14.6. <A
-HREF="#AEN2456"
+>10.6. <A
+HREF="#AEN1815"
>Accounts and Groups management</A
></DT
><DT
->14.7. <A
-HREF="#AEN2461"
+>10.7. <A
+HREF="#AEN1820"
>Security and sambaAccount</A
></DT
><DT
->14.8. <A
-HREF="#AEN2481"
+>10.8. <A
+HREF="#AEN1840"
>LDAP specials attributes for sambaAccounts</A
></DT
><DT
->14.9. <A
-HREF="#AEN2551"
+>10.9. <A
+HREF="#AEN1910"
>Example LDIF Entries for a sambaAccount</A
></DT
><DT
->14.10. <A
-HREF="#AEN2559"
+>10.10. <A
+HREF="#AEN1918"
>Comments</A
></DT
></DL
></DD
><DT
->15. <A
-HREF="#IMPROVED-BROWSING"
->Improved browsing in samba</A
+>11. <A
+HREF="#WINBIND"
+>Unified Logons between Windows NT and UNIX using Winbind</A
></DT
><DD
><DL
><DT
->15.1. <A
-HREF="#AEN2570"
->Overview of browsing</A
-></DT
-><DT
->15.2. <A
-HREF="#AEN2574"
->Browsing support in samba</A
+>11.1. <A
+HREF="#AEN1947"
+>Abstract</A
></DT
><DT
->15.3. <A
-HREF="#AEN2583"
->Problem resolution</A
+>11.2. <A
+HREF="#AEN1951"
+>Introduction</A
></DT
><DT
->15.4. <A
-HREF="#AEN2590"
->Browsing across subnets</A
+>11.3. <A
+HREF="#AEN1964"
+>What Winbind Provides</A
></DT
><DD
><DL
><DT
->15.4.1. <A
-HREF="#AEN2595"
->How does cross subnet browsing work ?</A
-></DT
-></DL
-></DD
-><DT
->15.5. <A
-HREF="#AEN2630"
->Setting up a WINS server</A
-></DT
-><DT
->15.6. <A
-HREF="#AEN2649"
->Setting up Browsing in a WORKGROUP</A
-></DT
-><DT
->15.7. <A
-HREF="#AEN2667"
->Setting up Browsing in a DOMAIN</A
-></DT
-><DT
->15.8. <A
-HREF="#AEN2677"
->Forcing samba to be the master</A
-></DT
-><DT
->15.9. <A
-HREF="#AEN2686"
->Making samba the domain master</A
-></DT
-><DT
->15.10. <A
-HREF="#AEN2704"
->Note about broadcast addresses</A
-></DT
-><DT
->15.11. <A
-HREF="#AEN2707"
->Multiple interfaces</A
+>11.3.1. <A
+HREF="#AEN1971"
+>Target Uses</A
></DT
></DL
></DD
><DT
->16. <A
-HREF="#SPEED"
->Samba performance issues</A
+>11.4. <A
+HREF="#AEN1975"
+>How Winbind Works</A
></DT
><DD
><DL
><DT
->16.1. <A
-HREF="#AEN2725"
->Comparisons</A
+>11.4.1. <A
+HREF="#AEN1980"
+>Microsoft Remote Procedure Calls</A
></DT
><DT
->16.2. <A
-HREF="#AEN2731"
->Oplocks</A
+>11.4.2. <A
+HREF="#AEN1984"
+>Name Service Switch</A
></DT
-><DD
-><DL
><DT
->16.2.1. <A
-HREF="#AEN2733"
->Overview</A
+>11.4.3. <A
+HREF="#AEN2000"
+>Pluggable Authentication Modules</A
></DT
><DT
->16.2.2. <A
-HREF="#AEN2741"
->Level2 Oplocks</A
+>11.4.4. <A
+HREF="#AEN2008"
+>User and Group ID Allocation</A
></DT
><DT
->16.2.3. <A
-HREF="#AEN2747"
->Old 'fake oplocks' option - deprecated</A
+>11.4.5. <A
+HREF="#AEN2012"
+>Result Caching</A
></DT
></DL
></DD
><DT
->16.3. <A
-HREF="#AEN2751"
->Socket options</A
-></DT
-><DT
->16.4. <A
-HREF="#AEN2758"
->Read size</A
-></DT
-><DT
->16.5. <A
-HREF="#AEN2763"
->Max xmit</A
+>11.5. <A
+HREF="#AEN2015"
+>Installation and Configuration</A
></DT
+><DD
+><DL
><DT
->16.6. <A
-HREF="#AEN2768"
->Locking</A
+>11.5.1. <A
+HREF="#AEN2022"
+>Introduction</A
></DT
><DT
->16.7. <A
-HREF="#AEN2772"
->Share modes</A
+>11.5.2. <A
+HREF="#AEN2035"
+>Requirements</A
></DT
><DT
->16.8. <A
-HREF="#AEN2777"
->Log level</A
+>11.5.3. <A
+HREF="#AEN2049"
+>Testing Things Out</A
></DT
+><DD
+><DL
><DT
->16.9. <A
-HREF="#AEN2780"
->Wide lines</A
+>11.5.3.1. <A
+HREF="#AEN2060"
+>Configure and compile SAMBA</A
></DT
><DT
->16.10. <A
-HREF="#AEN2783"
->Read raw</A
+>11.5.3.2. <A
+HREF="#AEN2079"
+>Configure <TT
+CLASS="FILENAME"
+>nsswitch.conf</TT
+> and the
+winbind libraries</A
></DT
><DT
->16.11. <A
-HREF="#AEN2788"
->Write raw</A
+>11.5.3.3. <A
+HREF="#AEN2104"
+>Configure smb.conf</A
></DT
><DT
->16.12. <A
-HREF="#AEN2792"
->Read prediction</A
+>11.5.3.4. <A
+HREF="#AEN2120"
+>Join the SAMBA server to the PDC domain</A
></DT
><DT
->16.13. <A
-HREF="#AEN2799"
->Memory mapping</A
+>11.5.3.5. <A
+HREF="#AEN2131"
+>Start up the winbindd daemon and test it!</A
></DT
><DT
->16.14. <A
-HREF="#AEN2804"
->Slow Clients</A
+>11.5.3.6. <A
+HREF="#AEN2167"
+>Fix the <TT
+CLASS="FILENAME"
+>/etc/rc.d/init.d/smb</TT
+> startup files</A
></DT
><DT
->16.15. <A
-HREF="#AEN2808"
->Slow Logins</A
+>11.5.3.7. <A
+HREF="#AEN2189"
+>Configure Winbind and PAM</A
></DT
+></DL
+></DD
+></DL
+></DD
><DT
->16.16. <A
-HREF="#AEN2811"
->Client tuning</A
+>11.6. <A
+HREF="#AEN2236"
+>Limitations</A
></DT
><DT
->16.17. <A
-HREF="#AEN2843"
->My Results</A
+>11.7. <A
+HREF="#AEN2246"
+>Conclusion</A
></DT
></DL
></DD
><DT
->17. <A
+>12. <A
HREF="#OS2"
>OS2 Client HOWTO</A
></DT
><DD
><DL
><DT
->17.1. <A
-HREF="#AEN2860"
+>12.1. <A
+HREF="#AEN2260"
>FAQs</A
></DT
><DD
><DL
><DT
->17.1.1. <A
-HREF="#AEN2862"
+>12.1.1. <A
+HREF="#AEN2262"
>How can I configure OS/2 Warp Connect or
OS/2 Warp 4 as a client for Samba?</A
></DT
><DT
->17.1.2. <A
-HREF="#AEN2877"
+>12.1.2. <A
+HREF="#AEN2277"
>How can I configure OS/2 Warp 3 (not Connect),
OS/2 1.2, 1.3 or 2.x for Samba?</A
></DT
><DT
->17.1.3. <A
-HREF="#AEN2886"
+>12.1.3. <A
+HREF="#AEN2286"
>Are there any other issues when OS/2 (any version)
is used as a client?</A
></DT
><DT
->17.1.4. <A
-HREF="#AEN2890"
+>12.1.4. <A
+HREF="#AEN2290"
>How do I get printer driver download working
for OS/2 clients?</A
></DT
@@ -1333,32 +994,32 @@ HREF="#AEN2890"
></DL
></DD
><DT
->18. <A
+>13. <A
HREF="#CVS-ACCESS"
>HOWTO Access Samba source code via CVS</A
></DT
><DD
><DL
><DT
->18.1. <A
-HREF="#AEN2906"
+>13.1. <A
+HREF="#AEN2306"
>Introduction</A
></DT
><DT
->18.2. <A
-HREF="#AEN2911"
+>13.2. <A
+HREF="#AEN2311"
>CVS Access to samba.org</A
></DT
><DD
><DL
><DT
->18.2.1. <A
-HREF="#AEN2914"
+>13.2.1. <A
+HREF="#AEN2314"
>Access via CVSweb</A
></DT
><DT
->18.2.2. <A
-HREF="#AEN2919"
+>13.2.2. <A
+HREF="#AEN2319"
>Access via cvs</A
></DT
></DL
@@ -1366,47 +1027,8 @@ HREF="#AEN2919"
></DL
></DD
><DT
->19. <A
-HREF="#BUGREPORT"
->Reporting Bugs</A
-></DT
-><DD
-><DL
-><DT
->19.1. <A
-HREF="#AEN2954"
->Introduction</A
-></DT
-><DT
->19.2. <A
-HREF="#AEN2961"
->General info</A
-></DT
-><DT
->19.3. <A
-HREF="#AEN2967"
->Debug levels</A
-></DT
-><DT
->19.4. <A
-HREF="#AEN2984"
->Internal errors</A
-></DT
-><DT
->19.5. <A
-HREF="#AEN2994"
->Attaching to a running process</A
-></DT
-><DT
->19.6. <A
-HREF="#AEN2997"
->Patches</A
-></DT
-></DL
-></DD
-><DT
><A
-HREF="#AEN3002"
+HREF="#AEN2347"
>Index</A
></DT
></DL
@@ -1900,7 +1522,7 @@ CLASS="REPLACEABLE"
></TT
></P
><P
->You should get back a list of shares available on
+>Your 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
@@ -2078,8 +1700,8 @@ NAME="AEN183"
>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
+ need to use the -i &#60;scope&#62; option to nmbd, smbd, and
+ smbclient. All your PCs will need to have the same setting for
this to work. I do not recommend scope IDs.</P
></DIV
><DIV
@@ -2200,13 +1822,19 @@ NAME="AEN199"
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
+><P
+>You can disable share modes using "share modes = no".
+ This may be useful on a heavily loaded server as the share
+ modes code is very slow. See also the FAST_SHARE_MODES
+ option in the Makefile for a way to do full share modes
+ very fast using shared memory (if your OS supports it).</P
></DIV
><DIV
CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN208"
+NAME="AEN209"
>1.10.6. Mapping Usernames</A
></H2
><P
@@ -2214,560 +1842,21 @@ NAME="AEN208"
the unix server then take a look at the "username map" option.
See the smb.conf man page for details.</P
></DIV
-></DIV
-></DIV
-><DIV
-CLASS="CHAPTER"
-><HR><H1
-><A
-NAME="DIAGNOSIS"
->Chapter 2. Diagnosing your samba server</A
-></H1
-><DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="AEN222"
->2.1. Introduction</A
-></H1
-><P
->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.</P
-><P
->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.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN227"
->2.2. Assumptions</A
-></H1
-><P
->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).</P
-><P
->The procedure is similar for other types of clients.</P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->&#13;[tmp]
- comment = temporary files
- path = /tmp
- read only = yes&#13;</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->THESE TESTS ASSUME VERSION 2.0.6 OR LATER OF THE SAMBA SUITE. SOME
-COMMANDS SHOWN DID NOT EXIST IN EARLIER VERSIONS</P
-><P
->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.</P
-><P
->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"</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN237"
->2.3. Tests</A
-></H1
-><DIV
-CLASS="SECT2"
-><H2
-CLASS="SECT2"
-><A
-NAME="AEN239"
->2.3.1. Test 1</A
-></H2
-><P
->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.</P
-><P
->Note: Your smb.conf file may be located in: <TT
-CLASS="FILENAME"
->/etc</TT
->
- Or in: <TT
-CLASS="FILENAME"
->/usr/local/samba/lib</TT
-></P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN245"
->2.3.2. Test 2</A
-></H2
-><P
->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. </P
-><P
->Note that you will need to start a "dos prompt" window on the PC to
-run ping.</P
-><P
->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. </P
-><P
->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.)</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN251"
->2.3.3. Test 3</A
-></H2
-><P
->Run the command "smbclient -L BIGSERVER" on the unix box. You
-should get a list of available shares back. </P
-><P
->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.</P
-><P
->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".</P
-><P
->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.</P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> hosts deny = ALL
- hosts allow = xxx.xxx.xxx.xxx/yy
- bind interfaces only = Yes</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> hosts deny = ALL
- hosts allow = xxx.xxx.xxx.xxx/yy 127.</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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).</P
-><P
->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!</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN266"
->2.3.4. Test 4</A
-></H2
-><P
->Run the command "nmblookup -B BIGSERVER __SAMBA__". You should get the
-IP address of your Samba server back.</P
-><P
->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.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN271"
->2.3.5. Test 5</A
-></H2
-><P
->run the command <B
-CLASS="COMMAND"
->nmblookup -B ACLIENT '*'</B
-></P
-><P
->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. </P
-><P
->If ACLIENT doesn't resolve via DNS then use the IP address of the
-client in the above test.</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN277"
->2.3.6. Test 6</A
-></H2
-><P
->Run the command <B
-CLASS="COMMAND"
->nmblookup -d 2 '*'</B
-></P
-><P
->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.</P
-><P
->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. </P
-><P
->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.</P
-><P
->This test will probably fail if your subnet mask and broadcast address are
-not correct. (Refer to TEST 3 notes above).</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN285"
->2.3.7. Test 7</A
-></H2
-><P
->Run the command <B
-CLASS="COMMAND"
->smbclient //BIGSERVER/TMP</B
->. 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 &#62;accountname&#60; option to the end of
-the command line. eg:
-<B
-CLASS="COMMAND"
->smbclient //bigserver/tmp -Ujohndoe</B
-></P
-><P
->Note: It is possible to specify the password along with the username
-as follows:
-<B
-CLASS="COMMAND"
->smbclient //bigserver/tmp -Ujohndoe%secret</B
-></P
-><P
->Once you enter the password you should get the "smb&#62;" 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.</P
-><P
->If it says "bad password" then the likely causes are:</P
-><P
-></P
-><OL
-TYPE="1"
-><LI
-><P
-> you have shadow passords (or some other password system) but didn't
- compile in support for them in smbd
- </P
-></LI
-><LI
-><P
-> your "valid users" configuration is incorrect
- </P
-></LI
-><LI
-><P
-> you have a mixed case password and you haven't enabled the "password
- level" option at a high enough level
- </P
-></LI
-><LI
-><P
-> the "path =" line in smb.conf is incorrect. Check it with testparm
- </P
-></LI
-><LI
-><P
-> you enabled password encryption but didn't create the SMB encrypted
- password file
- </P
-></LI
-></OL
-><P
->Once connected you should be able to use the commands
-<B
-CLASS="COMMAND"
->dir</B
-> <B
-CLASS="COMMAND"
->get</B
-> <B
-CLASS="COMMAND"
->put</B
-> etc.
-Type <B
-CLASS="COMMAND"
->help &#62;command&#60;</B
-> for instructions. You should
-especially check that the amount of free disk space shown is correct
-when you type <B
-CLASS="COMMAND"
->dir</B
->.</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN311"
->2.3.8. Test 8</A
-></H2
-><P
->On the PC type the command <B
-CLASS="COMMAND"
->net view \\BIGSERVER</B
->. You will
-need to do this from within a "dos prompt" window. You should get back a
-list of available shares on the server.</P
-><P
->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):</P
-><P
-></P
-><OL
-TYPE="1"
-><LI
-><P
-> fixup the nmbd installation</P
-></LI
-><LI
-><P
-> add the IP address of BIGSERVER to the "wins server" box in the
- advanced tcp/ip setup on the PC.</P
-></LI
-><LI
-><P
-> enable windows name resolution via DNS in the advanced section of
- the tcp/ip setup</P
-></LI
-><LI
-><P
-> add BIGSERVER to your lmhosts file on the PC.</P
-></LI
-></OL
-><P
->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)</P
-><P
->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.</P
-><P
->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.)</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN328"
->2.3.9. Test 9</A
-></H2
-><P
->Run the command <B
-CLASS="COMMAND"
->net use x: \\BIGSERVER\TMP</B
->. 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.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN333"
->2.3.10. Test 10</A
-></H2
-><P
->Run the command <B
-CLASS="COMMAND"
->nmblookup -M TESTGROUP</B
-> 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.</P
-><P
->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 <B
-CLASS="COMMAND"
->preferred master = yes</B
-> to ensure that
-an election is held at startup.</P
-></DIV
><DIV
CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN339"
->2.3.11. Test 11</A
+NAME="AEN212"
+>1.10.7. Other Character Sets</A
></H2
><P
->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
-<B
-CLASS="COMMAND"
->security = server</B
-> AND
-<B
-CLASS="COMMAND"
->password server = Windows_NT_Machine</B
-> in your
-smb.conf file, or enable encrypted passwords AFTER compiling in support
-for encrypted passwords (refer to the Makefile).</P
-></DIV
+>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
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN344"
->2.4. Still having troubles?</A
-></H1
-><P
->Try the mailing list or newsgroup, or use the ethereal utility to
-sniff the problem. The official samba mailing list can be reached at
-<A
-HREF="mailto:samba@samba.org"
-TARGET="_top"
->samba@samba.org</A
->. To find
-out more about samba and how to subscribe to the mailing list check
-out the samba web page at
-<A
-HREF="http://samba.org/samba"
-TARGET="_top"
->http://samba.org/samba</A
-></P
-><P
->Also look at the other docs in the Samba package!</P
></DIV
></DIV
><DIV
@@ -2775,15 +1864,15 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="INTEGRATE-MS-NETWORKS"
->Chapter 3. Integrating MS Windows networks with Samba</A
+>Chapter 2. Integrating MS Windows networks with Samba</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN361"
->3.1. Agenda</A
+NAME="AEN226"
+>2.1. Agenda</A
></H1
><P
>To identify the key functional mechanisms of MS Windows networking
@@ -2849,8 +1938,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN383"
->3.2. Name Resolution in a pure Unix/Linux world</A
+NAME="AEN248"
+>2.2. Name Resolution in a pure Unix/Linux world</A
></H1
><P
>The key configuration files covered in this section are:</P
@@ -2891,8 +1980,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN399"
->3.2.1. <TT
+NAME="AEN264"
+>2.2.1. <TT
CLASS="FILENAME"
>/etc/hosts</TT
></A
@@ -2954,7 +2043,7 @@ CLASS="FILENAME"
> 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
+determined a protocol called ARP/RARP isused 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
@@ -2981,8 +2070,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN415"
->3.2.2. <TT
+NAME="AEN280"
+>2.2.2. <TT
CLASS="FILENAME"
>/etc/resolv.conf</TT
></A
@@ -3019,8 +2108,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN426"
->3.2.3. <TT
+NAME="AEN291"
+>2.2.3. <TT
CLASS="FILENAME"
>/etc/host.conf</TT
></A
@@ -3057,8 +2146,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN434"
->3.2.4. <TT
+NAME="AEN299"
+>2.2.4. <TT
CLASS="FILENAME"
>/etc/nsswitch.conf</TT
></A
@@ -3135,8 +2224,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN446"
->3.3. Name resolution as used within MS Windows networking</A
+NAME="AEN311"
+>2.3. Name resolution as used within MS Windows networking</A
></H1
><P
>MS Windows networking is predicated about the name each machine
@@ -3204,7 +2293,7 @@ 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
+just a password (known as SHARE MORE 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
@@ -3229,13 +2318,13 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN458"
->3.3.1. The NetBIOS Name Cache</A
+NAME="AEN323"
+>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
+stored the NetBIOS names and their IP addresses for all external
+machines that that the local 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
@@ -3243,7 +2332,7 @@ configured name resolution mechanisms.</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
+to time-out delays. ie: It's 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
@@ -3256,8 +2345,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN463"
->3.3.2. The LMHOSTS file</A
+NAME="AEN328"
+>2.3.2. The LMHOSTS file</A
></H2
><P
>This file is usually located in MS Windows NT 4.0 or
@@ -3368,8 +2457,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN471"
->3.3.3. HOSTS file</A
+NAME="AEN336"
+>2.3.3. HOSTS file</A
></H2
><P
>This file is usually located in MS Windows NT 4.0 or 2000 in
@@ -3390,8 +2479,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN476"
->3.3.4. DNS Lookup</A
+NAME="AEN341"
+>2.3.4. DNS Lookup</A
></H2
><P
>This capability is configured in the TCP/IP setup area in the network
@@ -3410,8 +2499,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN479"
->3.3.5. WINS Lookup</A
+NAME="AEN344"
+>2.3.5. WINS Lookup</A
></H2
><P
>A WINS (Windows Internet Name Server) service is the equivaent of the
@@ -3471,13 +2560,13 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN491"
->3.4. How browsing functions and how to deploy stable and
+NAME="AEN356"
+>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
+(ie: 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
@@ -3502,7 +2591,7 @@ 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
+is held to determine which machine will be the master browser. By 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
@@ -3538,8 +2627,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN501"
->3.5. MS Windows security options and how to configure
+NAME="AEN366"
+>2.5. MS Windows security options and how to configure
Samba for seemless integration</A
></H1
><P
@@ -3587,8 +2676,8 @@ 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
+use the mapped drive connection that has been dropped the SMB protocol
+has a mechanism by which the connection can be re-established using
a cached copy of the password.</P
><P
>When Microsoft changed the default password mode, they dropped support for
@@ -3680,8 +2769,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN529"
->3.5.1. Use MS Windows NT as an authentication server</A
+NAME="AEN394"
+>2.5.1. Use MS Windows NT as an authentication server</A
></H2
><P
>This method involves the additions of the following parameters
@@ -3725,8 +2814,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN537"
->3.5.2. Make Samba a member of an MS Windows NT security domain</A
+NAME="AEN402"
+>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
@@ -3797,12 +2886,12 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN554"
->3.5.3. Configure Samba as an authentication server</A
+NAME="AEN419"
+>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
+Unix/Linux system both a Unix style account as well as and
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
@@ -3843,8 +2932,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN561"
->3.5.3.1. Users</A
+NAME="AEN426"
+>2.5.3.1. Users</A
></H3
><P
>A user account that may provide a home directory should be
@@ -3875,8 +2964,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN566"
->3.5.3.2. MS Windows NT Machine Accounts</A
+NAME="AEN431"
+>2.5.3.2. MS Windows NT Machine Accounts</A
></H3
><P
>These are required only when Samba is used as a domain
@@ -3905,8 +2994,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN571"
->3.6. Conclusions</A
+NAME="AEN436"
+>2.6. Conclusions</A
></H1
><P
>Samba provides a flexible means to operate as...</P
@@ -3942,7 +3031,7 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="PAM"
->Chapter 4. Configuring PAM for distributed but centrally
+>Chapter 3. Configuring PAM for distributed but centrally
managed authentication</A
></H1
><DIV
@@ -3950,8 +3039,8 @@ CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN592"
->4.1. Samba and PAM</A
+NAME="AEN457"
+>3.1. Samba and PAM</A
></H1
><P
>A number of Unix systems (eg: Sun Solaris), as well as the
@@ -4209,8 +3298,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN636"
->4.2. Distributed Authentication</A
+NAME="AEN501"
+>3.2. Distributed Authentication</A
></H1
><P
>The astute administrator will realize from this that the
@@ -4242,8 +3331,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN643"
->4.3. PAM Configuration in smb.conf</A
+NAME="AEN508"
+>3.3. PAM Configuration in smb.conf</A
></H1
><P
>There is an option in smb.conf called <A
@@ -4283,15 +3372,15 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="MSDFS"
->Chapter 5. Hosting a Microsoft Distributed File System tree on Samba</A
+>Chapter 4. Hosting a Microsoft Distributed File System tree on Samba</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN663"
->5.1. Instructions</A
+NAME="AEN528"
+>4.1. Instructions</A
></H1
><P
>The Distributed File System (or Dfs) provides a means of
@@ -4447,8 +3536,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN698"
->5.1.1. Notes</A
+NAME="AEN563"
+>4.1.1. Notes</A
></H2
><P
></P
@@ -4481,15 +3570,15 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="UNIX-PERMISSIONS"
->Chapter 6. UNIX Permission Bits and Windows NT Access Control Lists</A
+>Chapter 5. UNIX Permission Bits and Windows NT Access Control Lists</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN718"
->6.1. Viewing and changing UNIX permissions using the NT
+NAME="AEN583"
+>5.1. Viewing and changing UNIX permissions using the NT
security dialogs</A
></H1
><P
@@ -4527,8 +3616,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN727"
->6.2. How to view file security on a Samba share</A
+NAME="AEN592"
+>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
@@ -4573,8 +3662,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN738"
->6.3. Viewing file ownership</A
+NAME="AEN603"
+>5.3. Viewing file ownership</A
></H1
><P
>Clicking on the <B
@@ -4659,8 +3748,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN758"
->6.4. Viewing file or directory permissions</A
+NAME="AEN623"
+>5.4. Viewing file or directory permissions</A
></H1
><P
>The third button is the <B
@@ -4721,8 +3810,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN773"
->6.4.1. File Permissions</A
+NAME="AEN638"
+>5.4.1. File Permissions</A
></H2
><P
>The standard UNIX user/group/world triple and
@@ -4783,8 +3872,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN787"
->6.4.2. Directory Permissions</A
+NAME="AEN652"
+>5.4.2. Directory Permissions</A
></H2
><P
>Directories on an NT NTFS file system have two
@@ -4815,8 +3904,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN794"
->6.5. Modifying file or directory permissions</A
+NAME="AEN659"
+>5.5. Modifying file or directory permissions</A
></H1
><P
>Modifying file and directory permissions is as simple
@@ -4913,8 +4002,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN816"
->6.6. Interaction with the standard Samba create mask
+NAME="AEN681"
+>5.6. Interaction with the standard Samba create mask
parameters</A
></H1
><P
@@ -5186,8 +4275,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN880"
->6.7. Interaction with the standard Samba file attribute
+NAME="AEN745"
+>5.7. Interaction with the standard Samba file attribute
mapping</A
></H1
><P
@@ -5234,15 +4323,15 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="PRINTING"
->Chapter 7. Printing Support in Samba 2.2.x</A
+>Chapter 6. Printing Support in Samba 2.2.x</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN901"
->7.1. Introduction</A
+NAME="AEN766"
+>6.1. Introduction</A
></H1
><P
>Beginning with the 2.2.0 release, Samba supports
@@ -5325,8 +4414,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN923"
->7.2. Configuration</A
+NAME="AEN788"
+>6.2. Configuration</A
></H1
><DIV
CLASS="WARNING"
@@ -5393,8 +4482,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN934"
->7.2.1. Creating [print$]</A
+NAME="AEN799"
+>6.2.1. Creating [print$]</A
></H2
><P
>In order to support the uploading of printer driver
@@ -5596,8 +4685,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN969"
->7.2.2. Setting Drivers for Existing Printers</A
+NAME="AEN834"
+>6.2.2. Setting Drivers for Existing Printers</A
></H2
><P
>The initial listing of printers in the Samba host's
@@ -5668,8 +4757,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN986"
->7.2.3. Support a large number of printers</A
+NAME="AEN851"
+>6.2.3. Support a large number of printers</A
></H2
><P
>One issue that has arisen during the development
@@ -5743,8 +4832,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN997"
->7.2.4. Adding New Printers via the Windows NT APW</A
+NAME="AEN862"
+>6.2.4. Adding New Printers via the Windows NT APW</A
></H2
><P
>By default, Samba offers all printer shares defined in <TT
@@ -5849,8 +4938,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN1022"
->7.2.5. Samba and Printer Ports</A
+NAME="AEN887"
+>6.2.5. Samba and Printer Ports</A
></H2
><P
>Windows NT/2000 print servers associate a port with each printer. These normally
@@ -5886,8 +4975,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1030"
->7.3. The Imprints Toolset</A
+NAME="AEN895"
+>6.3. The Imprints Toolset</A
></H1
><P
>The Imprints tool set provides a UNIX equivalent of the
@@ -5904,8 +4993,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN1034"
->7.3.1. What is Imprints?</A
+NAME="AEN899"
+>6.3.1. What is Imprints?</A
></H2
><P
>Imprints is a collection of tools for supporting the goals
@@ -5936,8 +5025,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN1044"
->7.3.2. Creating Printer Driver Packages</A
+NAME="AEN909"
+>6.3.2. Creating Printer Driver Packages</A
></H2
><P
>The process of creating printer driver packages is beyond
@@ -5952,8 +5041,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN1047"
->7.3.3. The Imprints server</A
+NAME="AEN912"
+>6.3.3. The Imprints server</A
></H2
><P
>The Imprints server is really a database server that
@@ -5972,8 +5061,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN1051"
->7.3.4. The Installation Client</A
+NAME="AEN916"
+>6.3.4. The Installation Client</A
></H2
><P
>More information regarding the Imprints installation client
@@ -6075,8 +5164,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1073"
->7.4. <A
+NAME="AEN938"
+>6.4. <A
NAME="MIGRATION"
></A
>Migration to from Samba 2.0.x to 2.2.x</A
@@ -6231,668 +5320,16 @@ disabled by default.</P
CLASS="CHAPTER"
><HR><H1
><A
-NAME="PRINTING_DEBUG"
->Chapter 8. Debugging Printing Problems</A
-></H1
-><DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="AEN1119"
->8.1. Introduction</A
-></H1
-><P
->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.</P
-><P
->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.</P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> [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</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->The following are nice to know about:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> queuepause command - stop a printer or print queue
- queueresume command - start a printer or print queue</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->Example:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> 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
- queuepause command = /usr/sbin/lpc -P%p start</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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.</P
-><P
->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.</P
-><P
->The %&#62;letter&#60; 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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1135"
->8.2. Debugging printer problems</A
-></H1
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> print command = /tmp/saveprint %p %s
-
- #!/bin/saveprint
- # we make sure that we are the right user
- /usr/bin/id -p &#62;/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&#62;&#62;&#38;/tmp/tmp.print</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->&#13;h4: {42} % echo hi &#62;/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: \&#62; print /tmp/hi
-putting file /tmp/hi as hi-17534 (0.0 kb/s) (average 0.0 kb/s)
-smb: \&#62; queue
-1049 3 hi-17534
-smb: \&#62; cancel 1049
-Error cancelling job 1049 : code 0
-smb: \&#62; cancel 1049
-Job 1049 cancelled
-smb: \&#62; queue
-smb: \&#62; exit</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1144"
->8.3. What printers do I have?</A
-></H1
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> testprns printer /etc/printcap</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> testprns -a printer /etc/printcap
-
- testprns -a printer '|/bin/cat printcap'</PRE
-></TD
-></TR
-></TABLE
-></P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1152"
->8.4. Setting up printcap and print servers</A
-></H1
-><P
->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.</P
-><P
->Samba requires either a printcap or program to deliver printcap
-information. This printcap information has the format:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> name|alias1|alias2...:option=value:...</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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.</P
-><P
->Here are some examples of printcap files:</P
-><P
-><P
-></P
-><OL
-TYPE="1"
-><LI
-><P
->pr just printer name</P
-></LI
-><LI
-><P
->pr|alias printer name and alias</P
-></LI
-><LI
-><P
->pr|My Printer printer name, alias used as comment</P
-></LI
-><LI
-><P
->pr:sh:\ Same as pr:sh:cm= testing
- :cm= \
- testing</P
-></LI
-><LI
-><P
->pr:sh Same as pr:sh:cm= testing
- :cm= testing</P
-></LI
-></OL
-></P
-><P
->Samba reads the printcap information when first started. If you make
-changes in the printcap information, then you must do the following:</P
-><P
-></P
-><OL
-TYPE="1"
-><LI
-><P
->make sure that the print spooler is aware of these changes.
-The LPRng system uses the 'lpc reread' command to do this.</P
-></LI
-><LI
-><P
->make sure that the spool queues, etc., exist and have the
-correct permissions. The LPRng system uses the 'checkpc -f'
-command to do this.</P
-></LI
-><LI
-><P
->You now should send a SIGHUP signal to the smbd server to have
-it reread the printcap information.</P
-></LI
-></OL
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1180"
->8.5. Job sent, no output</A
-></H1
-><P
->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.</P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> lpc -Pprinter stop</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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.</P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> cd /var/spool/lpd/printer # spool directory of print jobs
- ls # find job files
- file dfA001myhost</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1191"
->8.6. Job sent, strange output</A
-></H1
-><P
->Once you have the job printing, you can then start worrying about
-making it print nicely.</P
-><P
->The most common problem is extra pages of output: banner pages
-OR blank pages at the end.</P
-><P
->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.</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> printer: ... :sh</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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.</P
-><P
->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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-> Printers|Printer Name|(Right Click)Properties|Postscript|Advanced|</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1203"
->8.7. Raw PostScript printed</A
-></H1
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1206"
->8.8. Advanced Printing</A
-></H1
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1209"
->8.9. Real debugging</A
-></H1
-><P
->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.</P
-></DIV
-></DIV
-><DIV
-CLASS="CHAPTER"
-><HR><H1
-><A
-NAME="SECURITY_LEVELS"
->Chapter 9. Security levels</A
-></H1
-><DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="AEN1222"
->9.1. Introduction</A
-></H1
-><P
->Samba supports the following options to the global smb.conf parameter</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->[global]
-<A
-HREF="smb.conf.5.html#SECURITY"
-TARGET="_top"
-><TT
-CLASS="PARAMETER"
-><I
->security</I
-></TT
-></A
-> = [share|user(default)|domain|ads]</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->Please refer to the smb.conf man page for usage information and to the document
-<A
-HREF="DOMAIN_MEMBER.html"
-TARGET="_top"
->DOMAIN_MEMBER.html</A
-> for further background details
-on domain mode security. The Windows 2000 Kerberos domain security model
-(security = ads) is described in the <A
-HREF="ADS-HOWTO.html"
-TARGET="_top"
->ADS-HOWTO.html</A
->.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1233"
->9.2. More complete description of security levels</A
-></H1
-><P
->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. </P
-><P
->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:</P
-><P
-></P
-><OL
-TYPE="1"
-><LI
-><P
->the username/password</P
-></LI
-><LI
-><P
->the machine that the client is coming from</P
-></LI
-></OL
-><P
->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". </P
-><P
->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)</P
-><P
->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".</P
-><P
->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.</P
-><P
->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". </P
-><P
->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.</P
-></DIV
-></DIV
-><DIV
-CLASS="CHAPTER"
-><HR><H1
-><A
NAME="DOMAIN-SECURITY"
->Chapter 10. security = domain in Samba 2.x</A
+>Chapter 7. security = domain in Samba 2.x</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN1266"
->10.1. Joining an NT Domain with Samba 2.2</A
+NAME="AEN992"
+>7.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
@@ -7122,8 +5559,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1330"
->10.2. Samba and Windows 2000 Domains</A
+NAME="AEN1056"
+>7.2. Samba and Windows 2000 Domains</A
></H1
><P
>Many people have asked regarding the state of Samba's ability to participate in
@@ -7147,8 +5584,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1335"
->10.3. Why is this better than security = server?</A
+NAME="AEN1061"
+>7.3. Why is this better than security = server?</A
></H1
><P
>Currently, domain security in Samba doesn't free you from
@@ -7233,1643 +5670,16 @@ TARGET="_top"
CLASS="CHAPTER"
><HR><H1
><A
-NAME="WINBIND"
->Chapter 11. Unified Logons between Windows NT and UNIX using Winbind</A
-></H1
-><DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="AEN1388"
->11.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="AEN1392"
->11.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="AEN1405"
->11.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="AEN1412"
->11.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="AEN1416"
->11.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="AEN1421"
->11.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="AEN1425"
->11.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="AEN1441"
->11.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="AEN1449"
->11.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="AEN1453"
->11.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="AEN1456"
->11.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 HOWTO for this section.</P
-><P
->This HOWTO describes how to get winbind services up and running
-to control access and authenticate users on your Linux box using
-the winbind services which come with SAMBA 2.2.2.</P
-><P
->There is also some Solaris specific information in
-<TT
-CLASS="FILENAME"
->docs/textdocs/Solaris-Winbind-HOWTO.txt</TT
->.
-Future revisions of this document will incorporate that
-information.</P
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN1463"
->11.5.1. Introduction</A
-></H2
-><P
->This HOWTO describes the procedures used to get winbind up and
-running on my 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 a nd ftp, as
-well for SAMBA services.</P
-><P
->This HOWTO has been written from a 'RedHat-centric' perspective, so if
-you are using another distribution, 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. That said, I am no NT or PAM
- expert, so you may find a better or easier way to accomplish
- these tasks.
- </P
-></LI
-></UL
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN1476"
->11.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
-> 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 yourmachine. 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
-> back to the original state they were in if
-you get frustrated with the way things are going. ;-)</P
-><P
->The latest version of SAMBA (version 2.2.2 as of this writing), now
-includes a functioning winbindd daemon. 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.</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 should have at least the pam libraries resident
-on your system. For recent RedHat systems (7.1, for instance), that
-means <TT
-CLASS="FILENAME"
->pam-0.74-22</TT
->. For best results, it is helpful to also
-install the development packages in <TT
-CLASS="FILENAME"
->pam-devel-0.74-22</TT
->.</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN1490"
->11.5.3. Testing Things Out</A
-></H2
-><P
->Before starting, it is probably best to 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. 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. Winbind built better
-in SAMBA if the pam-devel package was also installed. This package includes
-the header files needed to compile pam-aware applications. For instance,
-my RedHat system has both <TT
-CLASS="FILENAME"
->pam-0.74-22</TT
-> and
-<TT
-CLASS="FILENAME"
->pam-devel-0.74-22</TT
-> RPMs installed.</P
-><DIV
-CLASS="SECT3"
-><HR><H3
-CLASS="SECT3"
-><A
-NAME="AEN1501"
->11.5.3.1. Configure and compile SAMBA</A
-></H3
-><P
->The configuration and compilation of SAMBA is pretty straightforward.
-The first three steps may not be necessary depending upon
-whether or not you have previously built the Samba binaries.</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
-><TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->autoconf</B
->
-<TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->make clean</B
->
-<TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->rm config.cache</B
->
-<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 libraries. </P
-></DIV
-><DIV
-CLASS="SECT3"
-><HR><H3
-CLASS="SECT3"
-><A
-NAME="AEN1520"
->11.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, so</P
-><P
-><TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->cp ../samba/source/nsswitch/libnss_winbind.so /lib</B
-></P
-><P
->I also found 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
->And, in the case of Sun solaris:</P
-><P
-><TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->ln -s /usr/lib/libnss_winbind.so /usr/lib/libnss_winbind.so.1</B
->
-<TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->ln -s /usr/lib/libnss_winbind.so /usr/lib/nss_winbind.so.1</B
->
-<TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->ln -s /usr/lib/libnss_winbind.so /usr/lib/nss_winbind.so.2</B
-></P
-><P
->Now, as root you need to 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. My <TT
-CLASS="FILENAME"
->/etc/nsswitch.conf</TT
-> file look like
-this after editing:</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
-><P
->
-The libraries needed by the winbind daemon will be automatically
-entered into the <B
-CLASS="COMMAND"
->ldconfig</B
-> cache the next time
-your system reboots, but it
-is faster (and you don't need to reboot) if you do it manually:</P
-><P
-><TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->/sbin/ldconfig -v | grep winbind</B
-></P
-><P
->This makes <TT
-CLASS="FILENAME"
->libnss_winbind</TT
-> available to winbindd
-and echos back a check to you.</P
-></DIV
-><DIV
-CLASS="SECT3"
-><HR><H3
-CLASS="SECT3"
-><A
-NAME="AEN1553"
->11.5.3.3. Configure smb.conf</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
- <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 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="AEN1569"
->11.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/net rpc join -s 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="AEN1580"
->11.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"
->/usr/local/samba/bin/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
->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"
->/usr/local/samba/bin/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.</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="AEN1616"
->11.5.3.6. Fix the init.d startup scripts</A
-></H3
-><DIV
-CLASS="SECT4"
-><H4
-CLASS="SECT4"
-><A
-NAME="AEN1618"
->11.5.3.6.1. Linux</A
-></H4
-><P
->The <B
-CLASS="COMMAND"
->winbindd</B
-> daemon needs to start up after the
-<B
-CLASS="COMMAND"
->smbd</B
-> and <B
-CLASS="COMMAND"
->nmbd</B
-> daemons are running.
-To accomplish this task, you need to modify the startup scripts of your system. They are located at <TT
-CLASS="FILENAME"
->/etc/init.d/smb</TT
-> in RedHat and
-<TT
-CLASS="FILENAME"
->/etc/init.d/samba</TT
-> in Debian.
-script to add commands to invoke this daemon in the proper sequence. My
-startup script starts up <B
-CLASS="COMMAND"
->smbd</B
->,
-<B
-CLASS="COMMAND"
->nmbd</B
->, and <B
-CLASS="COMMAND"
->winbindd</B
-> from the
-<TT
-CLASS="FILENAME"
->/usr/local/samba/bin</TT
-> directory directly. The 'start'
-function in the script looks like this:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->start() {
- KIND="SMB"
- echo -n $"Starting $KIND services: "
- daemon /usr/local/samba/bin/smbd $SMBDOPTIONS
- RETVAL=$?
- echo
- KIND="NMB"
- echo -n $"Starting $KIND services: "
- daemon /usr/local/samba/bin/nmbd $NMBDOPTIONS
- RETVAL2=$?
- echo
- KIND="Winbind"
- echo -n $"Starting $KIND services: "
- daemon /usr/local/samba/bin/winbindd
- RETVAL3=$?
- echo
- [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 -a $RETVAL3 -eq 0 ] &#38;&#38; touch /var/lock/subsys/smb || \
- RETVAL=1
- return $RETVAL
-}</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->The 'stop' function has a corresponding entry to shut down the
-services and look s like this:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->stop() {
- KIND="SMB"
- echo -n $"Shutting down $KIND services: "
- killproc smbd
- RETVAL=$?
- echo
- KIND="NMB"
- echo -n $"Shutting down $KIND services: "
- killproc nmbd
- RETVAL2=$?
- echo
- KIND="Winbind"
- echo -n $"Shutting down $KIND services: "
- killproc winbindd
- RETVAL3=$?
- [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 -a $RETVAL3 -eq 0 ] &#38;&#38; rm -f /var/lock/subsys/smb
- echo ""
- return $RETVAL
-}</PRE
-></TD
-></TR
-></TABLE
-></P
-></DIV
-><DIV
-CLASS="SECT4"
-><HR><H4
-CLASS="SECT4"
-><A
-NAME="AEN1635"
->11.5.3.6.2. Solaris</A
-></H4
-><P
->On solaris, you need to modify the
-<TT
-CLASS="FILENAME"
->/etc/init.d/samba.server</TT
-> startup script. It usually
-only starts smbd and nmbd but should now start winbindd too. If you
-have samba installed in <TT
-CLASS="FILENAME"
->/usr/local/samba/bin</TT
->,
-the file could contains something like this:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->##
-## samba.server
-##
-
-if [ ! -d /usr/bin ]
-then # /usr not mounted
- exit
-fi
-
-killproc() { # kill the named process(es)
- pid=`/usr/bin/ps -e |
- /usr/bin/grep -w $1 |
- /usr/bin/sed -e 's/^ *//' -e 's/ .*//'`
- [ "$pid" != "" ] &#38;&#38; kill $pid
-}
-
-# Start/stop processes required for samba server
-
-case "$1" in
-
-'start')
-#
-# Edit these lines to suit your installation (paths, workgroup, host)
-#
-echo Starting SMBD
- /usr/local/samba/bin/smbd -D -s \
- /usr/local/samba/smb.conf
-
-echo Starting NMBD
- /usr/local/samba/bin/nmbd -D -l \
- /usr/local/samba/var/log -s /usr/local/samba/smb.conf
-
-echo Starting Winbind Daemon
- /usr/local/samba/bin/winbindd
- ;;
-
-'stop')
- killproc nmbd
- killproc smbd
- killproc winbindd
- ;;
-
-*)
- echo "Usage: /etc/init.d/samba.server { start | stop }"
- ;;
-esac</PRE
-></TD
-></TR
-></TABLE
-></P
-></DIV
-><DIV
-CLASS="SECT4"
-><HR><H4
-CLASS="SECT4"
-><A
-NAME="AEN1642"
->11.5.3.6.3. Restarting</A
-></H4
-><P
->If you restart the <B
-CLASS="COMMAND"
->smbd</B
->, <B
-CLASS="COMMAND"
->nmbd</B
->,
-and <B
-CLASS="COMMAND"
->winbindd</B
-> daemons at this point, you
-should be able to connect to the samba server as a domain member just as
-if you were a local user.</P
-></DIV
-></DIV
-><DIV
-CLASS="SECT3"
-><HR><H3
-CLASS="SECT3"
-><A
-NAME="AEN1648"
->11.5.3.7. Configure Winbind and PAM</A
-></H3
-><P
->If you have made it this far, you know that winbindd and samba 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
-> files? If not, do it now.)</P
-><P
->You will need a pam module to use winbindd 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 my RedHat system, this was the
-<TT
-CLASS="FILENAME"
->/lib/security</TT
-> directory. On Solaris, the pam security
-modules reside in <TT
-CLASS="FILENAME"
->/usr/lib/security</TT
->.</P
-><P
-><TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->cp ../samba/source/nsswitch/pam_winbind.so /lib/security</B
-></P
-><DIV
-CLASS="SECT4"
-><HR><H4
-CLASS="SECT4"
-><A
-NAME="AEN1665"
->11.5.3.7.1. Linux/FreeBSD-specific PAM configuration</A
-></H4
-><P
->The <TT
-CLASS="FILENAME"
->/etc/pam.d/samba</TT
-> file does not need to be changed. I
-just left this fileas it was:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->auth required /lib/security/pam_stack.so service=system-auth
-account required /lib/security/pam_stack.so service=system-auth</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->The other services that I modified to allow the use of winbind
-as an authentication service were the normal login on the console (or a terminal
-session), telnet logins, and ftp 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
-></DIV
-><DIV
-CLASS="SECT4"
-><HR><H4
-CLASS="SECT4"
-><A
-NAME="AEN1698"
->11.5.3.7.2. Solaris-specific configuration</A
-></H4
-><P
->The /etc/pam.conf needs to be changed. I changed this file so that my Domain
-users can logon both locally as well as telnet.The following are the changes
-that I made.You can customize the pam.conf file as per your requirements,but
-be sure of those changes because in the worst case it will leave your system
-nearly impossible to boot.</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->#
-#ident "@(#)pam.conf 1.14 99/09/16 SMI"
-#
-# Copyright (c) 1996-1999, Sun Microsystems, Inc.
-# All Rights Reserved.
-#
-# PAM configuration
-#
-# Authentication management
-#
-login auth required /usr/lib/security/pam_winbind.so
-login auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-login auth required /usr/lib/security/$ISA/pam_dial_auth.so.1 try_first_pass
-#
-rlogin auth sufficient /usr/lib/security/pam_winbind.so
-rlogin auth sufficient /usr/lib/security/$ISA/pam_rhosts_auth.so.1
-rlogin auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-dtlogin auth sufficient /usr/lib/security/pam_winbind.so
-dtlogin auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-rsh auth required /usr/lib/security/$ISA/pam_rhosts_auth.so.1
-other auth sufficient /usr/lib/security/pam_winbind.so
-other auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-# Account management
-#
-login account sufficient /usr/lib/security/pam_winbind.so
-login account requisite /usr/lib/security/$ISA/pam_roles.so.1
-login account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-dtlogin account sufficient /usr/lib/security/pam_winbind.so
-dtlogin account requisite /usr/lib/security/$ISA/pam_roles.so.1
-dtlogin account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-other account sufficient /usr/lib/security/pam_winbind.so
-other account requisite /usr/lib/security/$ISA/pam_roles.so.1
-other account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Session management
-#
-other session required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Password management
-#
-#other password sufficient /usr/lib/security/pam_winbind.so
-other password required /usr/lib/security/$ISA/pam_unix.so.1
-dtsession auth required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Support for Kerberos V5 authentication (uncomment to use Kerberos)
-#
-#rlogin auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#login auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#dtlogin auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#other auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#dtlogin account optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other account optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other session optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other password optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->I also added a try_first_pass line after the winbind.so line to get rid of
-annoying double prompts for passwords.</P
-><P
->Now restart your Samba &#38; try connecting through your application that you
-configured in the pam.conf.</P
-></DIV
-></DIV
-></DIV
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN1705"
->11.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
->Winbind is currently only available for
- the Linux operating system, although ports to other operating
- systems are certainly possible. For such ports to be feasible,
- we require the C library of the target operating system to
- support the Name Service Switch and Pluggable Authentication
- Modules systems. This is becoming more common as NSS and
- PAM gain support among UNIX vendors.</P
-></LI
-><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="AEN1715"
->11.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="SAMBA-PDC"
->Chapter 12. How to Configure Samba 2.2 as a Primary Domain Controller</A
+>Chapter 8. How to Configure Samba 2.2 as a Primary Domain Controller</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN1735"
->12.1. Prerequisite Reading</A
+NAME="AEN1094"
+>8.1. Prerequisite Reading</A
></H1
><P
>Before you continue reading in this chapter, please make sure
@@ -8896,8 +5706,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1741"
->12.2. Background</A
+NAME="AEN1100"
+>8.2. Background</A
></H1
><DIV
CLASS="NOTE"
@@ -9028,8 +5838,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1780"
->12.3. Configuring the Samba Domain Controller</A
+NAME="AEN1139"
+>8.3. Configuring the Samba Domain Controller</A
></H1
><P
>The first step in creating a working Samba PDC is to
@@ -9249,8 +6059,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1823"
->12.4. Creating Machine Trust Accounts and Joining Clients to the
+NAME="AEN1182"
+>8.4. Creating Machine Trust Accounts and Joining Clients to the
Domain</A
></H1
><P
@@ -9323,8 +6133,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN1842"
->12.4.1. Manual Creation of Machine Trust Accounts</A
+NAME="AEN1201"
+>8.4.1. Manual Creation of Machine Trust Accounts</A
></H2
><P
>The first step in manually creating a machine trust account is to
@@ -9490,8 +6300,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN1877"
->12.4.2. "On-the-Fly" Creation of Machine Trust Accounts</A
+NAME="AEN1236"
+>8.4.2. "On-the-Fly" Creation of Machine Trust Accounts</A
></H2
><P
>The second (and recommended) way of creating machine trust accounts is
@@ -9536,8 +6346,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN1886"
->12.4.3. Joining the Client to the Domain</A
+NAME="AEN1245"
+>8.4.3. Joining the Client to the Domain</A
></H2
><P
>The procedure for joining a client to the domain varies with the
@@ -9596,8 +6406,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1901"
->12.5. Common Problems and Errors</A
+NAME="AEN1260"
+>8.5. Common Problems and Errors</A
></H1
><P
></P
@@ -9795,8 +6605,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1949"
->12.6. System Policies and Profiles</A
+NAME="AEN1308"
+>8.6. System Policies and Profiles</A
></H1
><P
>Much of the information necessary to implement System Policies and
@@ -9952,8 +6762,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN1993"
->12.7. What other help can I get?</A
+NAME="AEN1352"
+>8.7. What other help can I get?</A
></H1
><P
>There are many sources of information available in the form
@@ -10348,8 +7158,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2107"
->12.8. Domain Control for Windows 9x/ME</A
+NAME="AEN1466"
+>8.8. Domain Control for Windows 9x/ME</A
></H1
><DIV
CLASS="NOTE"
@@ -10462,8 +7272,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2133"
->12.8.1. Configuration Instructions: Network Logons</A
+NAME="AEN1492"
+>8.8.1. Configuration Instructions: Network Logons</A
></H2
><P
>The main difference between a PDC and a Windows 9x logon
@@ -10556,8 +7366,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2152"
->12.8.2. Configuration Instructions: Setting up Roaming User Profiles</A
+NAME="AEN1511"
+>8.8.2. Configuration Instructions: Setting up Roaming User Profiles</A
></H2
><DIV
CLASS="WARNING"
@@ -10603,8 +7413,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN2160"
->12.8.2.1. Windows NT Configuration</A
+NAME="AEN1519"
+>8.8.2.1. Windows NT Configuration</A
></H3
><P
>To support WinNT clients, in the [global] section of smb.conf set the
@@ -10647,8 +7457,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN2168"
->12.8.2.2. Windows 9X Configuration</A
+NAME="AEN1527"
+>8.8.2.2. Windows 9X Configuration</A
></H3
><P
>To support Win9X clients, you must use the "logon home" parameter. Samba has
@@ -10687,8 +7497,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN2176"
->12.8.2.3. Win9X and WinNT Configuration</A
+NAME="AEN1535"
+>8.8.2.3. Win9X and WinNT Configuration</A
></H3
><P
>You can support profiles for both Win9X and WinNT clients by setting both the
@@ -10725,8 +7535,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN2183"
->12.8.2.4. Windows 9X Profile Setup</A
+NAME="AEN1542"
+>8.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,
@@ -10881,8 +7691,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN2219"
->12.8.2.5. Windows NT Workstation 4.0</A
+NAME="AEN1578"
+>8.8.2.5. Windows NT Workstation 4.0</A
></H3
><P
>When a user first logs in to a Windows NT Workstation, the profile
@@ -10963,8 +7773,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN2232"
->12.8.2.6. Windows NT Server</A
+NAME="AEN1591"
+>8.8.2.6. Windows NT Server</A
></H3
><P
>There is nothing to stop you specifying any path that you like for the
@@ -10977,8 +7787,8 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN2235"
->12.8.2.7. Sharing Profiles between W95 and NT Workstation 4.0</A
+NAME="AEN1594"
+>8.8.2.7. Sharing Profiles between W95 and NT Workstation 4.0</A
></H3
><DIV
CLASS="WARNING"
@@ -11005,7 +7815,7 @@ ALIGN="LEFT"
></TABLE
></DIV
><P
->The default logon path is \\%N\%U. NT Workstation will attempt to create
+>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".
@@ -11042,8 +7852,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2245"
->12.9. DOMAIN_CONTROL.txt : Windows NT Domain Control &#38; Samba</A
+NAME="AEN1604"
+>8.9. DOMAIN_CONTROL.txt : Windows NT Domain Control &#38; Samba</A
></H1
><DIV
CLASS="WARNING"
@@ -11164,15 +7974,15 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="SAMBA-BDC"
->Chapter 13. How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain</A
+>Chapter 9. How to Act as a Backup Domain Controller in a Purely Samba Controlled Domain</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN2281"
->13.1. Prerequisite Reading</A
+NAME="AEN1640"
+>9.1. Prerequisite Reading</A
></H1
><P
>Before you continue reading in this chapter, please make sure
@@ -11188,8 +7998,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2285"
->13.2. Background</A
+NAME="AEN1644"
+>9.2. Background</A
></H1
><P
>What is a Domain Controller? It is a machine that is able to answer
@@ -11242,8 +8052,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2293"
->13.3. What qualifies a Domain Controller on the network?</A
+NAME="AEN1652"
+>9.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
@@ -11259,8 +8069,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2296"
->13.3.1. How does a Workstation find its domain controller?</A
+NAME="AEN1655"
+>9.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
@@ -11278,8 +8088,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2299"
->13.3.2. When is the PDC needed?</A
+NAME="AEN1658"
+>9.3.2. When is the PDC needed?</A
></H2
><P
>Whenever a user wants to change his password, this has to be done on
@@ -11294,8 +8104,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2302"
->13.4. Can Samba be a Backup Domain Controller?</A
+NAME="AEN1661"
+>9.4. Can Samba be a Backup Domain Controller?</A
></H1
><P
>With version 2.2, no. The native NT SAM replication protocols have
@@ -11313,8 +8123,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2306"
->13.5. How do I set up a Samba BDC?</A
+NAME="AEN1665"
+>9.5. How do I set up a Samba BDC?</A
></H1
><P
>Several things have to be done:</P
@@ -11383,8 +8193,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2322"
->13.5.1. How do I replicate the smbpasswd file?</A
+NAME="AEN1681"
+>9.5.1. How do I replicate the smbpasswd file?</A
></H2
><P
>Replication of the smbpasswd file is sensitive. It has to be done
@@ -11406,15 +8216,15 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="SAMBA-LDAP-HOWTO"
->Chapter 14. Storing Samba's User/Machine Account information in an LDAP Directory</A
+>Chapter 10. Storing Samba's User/Machine Account information in an LDAP Directory</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN2343"
->14.1. Purpose</A
+NAME="AEN1702"
+>10.1. Purpose</A
></H1
><P
>This document describes how to use an LDAP directory for storing Samba user
@@ -11481,8 +8291,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2363"
->14.2. Introduction</A
+NAME="AEN1722"
+>10.2. Introduction</A
></H1
><P
>Traditionally, when configuring <A
@@ -11598,8 +8408,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2392"
->14.3. Supported LDAP Servers</A
+NAME="AEN1751"
+>10.3. Supported LDAP Servers</A
></H1
><P
>The LDAP samdb code in 2.2.3 has been developed and tested using the OpenLDAP
@@ -11623,8 +8433,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2397"
->14.4. Schema and Relationship to the RFC 2307 posixAccount</A
+NAME="AEN1756"
+>10.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
@@ -11691,16 +8501,16 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2409"
->14.5. Configuring Samba with LDAP</A
+NAME="AEN1768"
+>10.5. Configuring Samba with LDAP</A
></H1
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
-NAME="AEN2411"
->14.5.1. OpenLDAP configuration</A
+NAME="AEN1770"
+>10.5.1. OpenLDAP configuration</A
></H2
><P
>To include support for the sambaAccount object in an OpenLDAP directory
@@ -11799,8 +8609,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2428"
->14.5.2. Configuring Samba</A
+NAME="AEN1787"
+>10.5.2. Configuring Samba</A
></H2
><P
>The following parameters are available in smb.conf only with <TT
@@ -11928,8 +8738,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2456"
->14.6. Accounts and Groups management</A
+NAME="AEN1815"
+>10.6. Accounts and Groups management</A
></H1
><P
>As users accounts are managed thru the sambaAccount objectclass, you should
@@ -11953,8 +8763,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2461"
->14.7. Security and sambaAccount</A
+NAME="AEN1820"
+>10.7. Security and sambaAccount</A
></H1
><P
>There are two important points to remember when discussing the security
@@ -12033,8 +8843,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2481"
->14.8. LDAP specials attributes for sambaAccounts</A
+NAME="AEN1840"
+>10.8. LDAP specials attributes for sambaAccounts</A
></H1
><P
>The sambaAccount objectclass is composed of the following attributes:</P
@@ -12244,8 +9054,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2551"
->14.9. Example LDIF Entries for a sambaAccount</A
+NAME="AEN1910"
+>10.9. Example LDIF Entries for a sambaAccount</A
></H1
><P
>The following is a working LDIF with the inclusion of the posixAccount objectclass:</P
@@ -12320,8 +9130,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2559"
->14.10. Comments</A
+NAME="AEN1918"
+>10.10. Comments</A
></H1
><P
>Please mail all comments regarding this HOWTO to <A
@@ -12336,159 +9146,569 @@ last updated to reflect the Samba 2.2.3 release.&#13;</P
CLASS="CHAPTER"
><HR><H1
><A
-NAME="IMPROVED-BROWSING"
->Chapter 15. Improved browsing in samba</A
+NAME="WINBIND"
+>Chapter 11. Unified Logons between Windows NT and UNIX using Winbind</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN2570"
->15.1. Overview of browsing</A
+NAME="AEN1947"
+>11.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="AEN1951"
+>11.2. Introduction</A
></H1
><P
->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.</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
->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.</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="AEN2574"
->15.2. Browsing support in samba</A
+NAME="AEN1964"
+>11.3. What Winbind Provides</A
></H1
><P
->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)).</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
->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.</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
->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.</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
->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.</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
->[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].</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="AEN1971"
+>11.3.1. Target Uses</A
+></H2
><P
->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.</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
->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. </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="AEN2583"
->15.3. Problem resolution</A
+NAME="AEN1975"
+>11.4. How Winbind Works</A
></H1
><P
->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.</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="AEN1980"
+>11.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="AEN1984"
+>11.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="AEN2000"
+>11.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
->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.</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="AEN2008"
+>11.4.4. User and Group ID Allocation</A
+></H2
><P
->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.</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
->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.</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="AEN2012"
+>11.4.5. Result Caching</A
+></H2
><P
->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)</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="AEN2590"
->15.4. Browsing across subnets</A
+NAME="AEN2015"
+>11.5. Installation and Configuration</A
></H1
><P
->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.</P
-><P
->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.</P
-><P
->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.</P
+>Many thanks to John Trostel <A
+HREF="mailto:jtrostel@snapserver.com"
+TARGET="_top"
+>jtrostel@snapserver.com</A
+>
+for providing the HOWTO for this section.</P
+><P
+>This HOWTO describes how to get winbind services up and running
+to control access and authenticate users on your Linux box using
+the winbind services which come with SAMBA 2.2.2.</P
+><P
+>There is also some Solaris specific information in
+<TT
+CLASS="FILENAME"
+>docs/textdocs/Solaris-Winbind-HOWTO.txt</TT
+>.
+Future revisions of this document will incorporate that
+information.</P
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2022"
+>11.5.1. Introduction</A
+></H2
+><P
+>This HOWTO describes the procedures used to get winbind up and
+running on my 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 a nd ftp, as
+well for SAMBA services.</P
+><P
+>This HOWTO has been written from a 'RedHat-centric' perspective, so if
+you are using another distribution, 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. That said, I am no NT or PAM
+ expert, so you may find a better or easier way to accomplish
+ these tasks.
+ </P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="SECT2"
+><HR><H2
+CLASS="SECT2"
+><A
+NAME="AEN2035"
+>11.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
+> 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 yourmachine. 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
+> back to the original state they were in if
+you get frustrated with the way things are going. ;-)</P
+><P
+>The latest version of SAMBA (version 2.2.2 as of this writing), now
+includes a functioning winbindd daemon. 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.</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 should have at least the pam libraries resident
+on your system. For recent RedHat systems (7.1, for instance), that
+means <TT
+CLASS="FILENAME"
+>pam-0.74-22</TT
+>. For best results, it is helpful to also
+install the development packages in <TT
+CLASS="FILENAME"
+>pam-devel-0.74-22</TT
+>.</P
+></DIV
><DIV
CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2595"
->15.4.1. How does cross subnet browsing work ?</A
+NAME="AEN2049"
+>11.5.3. Testing Things Out</A
></H2
><P
->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.</P
+>Before starting, it is probably best to 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. 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. Winbind built better
+in SAMBA if the pam-devel package was also installed. This package includes
+the header files needed to compile pam-aware applications. For instance,
+my RedHat system has both <TT
+CLASS="FILENAME"
+>pam-0.74-22</TT
+> and
+<TT
+CLASS="FILENAME"
+>pam-devel-0.74-22</TT
+> RPMs installed.</P
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2060"
+>11.5.3.1. Configure and compile SAMBA</A
+></H3
><P
->Consider a network set up as follows :</P
+>The configuration and compilation of SAMBA is pretty straightforward.
+The first three steps may not be necessary depending upon
+whether or not you have previously built the Samba binaries.</P
><P
><TABLE
BORDER="0"
@@ -12498,65 +9718,110 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
-> (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)</PRE
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>autoconf</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>make clean</B
+>
+<TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>rm config.cache</B
+>
+<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
->Consisting of 3 subnets (1, 2, 3) connected 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.</P
-><P
->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.</P
-><P
->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.</P
-><P
->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'.</P
-><P
->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).</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 libraries. </P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2079"
+>11.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, so</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>cp ../samba/source/nsswitch/libnss_winbind.so /lib</B
+></P
+><P
+>I also found 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
+>Now, as root you need to 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. My <TT
+CLASS="FILENAME"
+>/etc/nsswitch.conf</TT
+> file look like
+this after editing:</P
><P
><TABLE
BORDER="0"
@@ -12566,37 +9831,65 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
->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</PRE
+> passwd: files winbind
+ shadow: files
+ group: files winbind</PRE
></TD
></TR
></TABLE
></P
><P
->Note that at this point all the subnets are separate, no
-machine is seen across any of the subnets.</P
+>
+The libraries needed by the winbind daemon will be automatically
+entered into the <B
+CLASS="COMMAND"
+>ldconfig</B
+> cache the next time
+your system reboots, but it
+is faster (and you don't need to reboot) if you do it manually:</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>/sbin/ldconfig -v | grep winbind</B
+></P
><P
->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&#62;1B&#60;. This name was registerd by the Domain master
-browser (N1_C) with the WINS server as soon as it was booted.</P
+>This makes <TT
+CLASS="FILENAME"
+>libnss_winbind</TT
+> available to winbindd
+and echos back a check to you.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
+><A
+NAME="AEN2104"
+>11.5.3.3. Configure smb.conf</A
+></H3
><P
->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 :</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"
@@ -12606,32 +9899,151 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
->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.</PRE
+>[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
+ <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 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="AEN2120"
+>11.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/net rpc join -s 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="AEN2131"
+>11.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"
+>/usr/local/samba/bin/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
+>Now... for the real test, try to get some information about the
+users on your PDC</P
><P
->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.</P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>/usr/local/samba/bin/wbinfo -u</B
+></P
><P
->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.</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"
@@ -12641,33 +10053,27 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
->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.</PRE
+>CEO+Administrator
+CEO+burdell
+CEO+Guest
+CEO+jt-ad
+CEO+krbtgt
+CEO+TsInternetUser</PRE
></TD
></TR
></TABLE
></P
><P
->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.</P
+>Obviously, I have named my domain 'CEO' and my <TT
+CLASS="PARAMETER"
+><I
+>winbind
+separator</I
+></TT
+> is '+'.</P
><P
->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 :</P
+>You can do the same sort of thing to get group information from
+the PDC:</P
><P
><TABLE
BORDER="0"
@@ -12677,176 +10083,246 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
->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.</PRE
+><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
->Synchronizations between the domain master browser and local
-master browsers will continue to occur, but this should be a
-steady state situation.</P
-><P
->If either router R1 or R2 fails the following will occur:</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
-><OL
-TYPE="1"
-><LI
><P
-> 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.
- </P
-></LI
-><LI
+>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.</P
><P
-> Attempts to connect to these inaccessible computers will fail, but the
- names will not be removed from the network neighbourhood lists.
- </P
-></LI
-><LI
+>The same thing can be done for groups with the command</P
><P
-> 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.
- </P
-></LI
-></OL
-></DIV
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
+CLASS="COMMAND"
+>getent group</B
+></P
></DIV
><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
><A
-NAME="AEN2630"
->15.5. Setting up a WINS server</A
-></H1
-><P
->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 </P
+NAME="AEN2167"
+>11.5.3.6. Fix the <TT
+CLASS="FILENAME"
+>/etc/rc.d/init.d/smb</TT
+> startup files</A
+></H3
><P
-><B
+>The <B
CLASS="COMMAND"
-> wins support = yes</B
-></P
-><P
->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.</P
-><P
->Machines with "<B
+>winbindd</B
+> daemon needs to start up after the
+<B
CLASS="COMMAND"
->wins support = yes</B
->" will keep a list of
-all NetBIOS names registered with them, acting as a DNS for NetBIOS names.</P
-><P
->You should set up only ONE wins server. Do NOT set the
-"<B
+>smbd</B
+> and <B
CLASS="COMMAND"
->wins support = yes</B
->" option on more than one Samba
-server.</P
-><P
->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-&#62;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.</P
-><P
->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-&#62;Network-&#62;Protocols-&#62;TCP-&#62;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 :</P
-><P
-><B
+>nmbd</B
+> daemons are running.
+To accomplish this task, you need to modify the <TT
+CLASS="FILENAME"
+>/etc/init.d/smb</TT
+>
+script to add commands to invoke this daemon in the proper sequence. My
+<TT
+CLASS="FILENAME"
+>/etc/init.d/smb</TT
+> file starts up <B
+CLASS="COMMAND"
+>smbd</B
+>,
+<B
+CLASS="COMMAND"
+>nmbd</B
+>, and <B
CLASS="COMMAND"
-> wins server = &#62;name or IP address&#60;</B
+>winbindd</B
+> from the
+<TT
+CLASS="FILENAME"
+>/usr/local/samba/bin</TT
+> directory directly. The 'start'
+function in the script looks like this:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>start() {
+ KIND="SMB"
+ echo -n $"Starting $KIND services: "
+ daemon /usr/local/samba/bin/smbd $SMBDOPTIONS
+ RETVAL=$?
+ echo
+ KIND="NMB"
+ echo -n $"Starting $KIND services: "
+ daemon /usr/local/samba/bin/nmbd $NMBDOPTIONS
+ RETVAL2=$?
+ echo
+ KIND="Winbind"
+ echo -n $"Starting $KIND services: "
+ daemon /usr/local/samba/bin/winbindd
+ RETVAL3=$?
+ echo
+ [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 -a $RETVAL3 -eq 0 ] &#38;&#38; touch /var/lock/subsys/smb || \
+ RETVAL=1
+ return $RETVAL
+}</PRE
+></TD
+></TR
+></TABLE
></P
><P
->where &#62;name or IP address&#60; is either the DNS name of the WINS server
-machine or its IP address.</P
+>The 'stop' function has a corresponding entry to shut down the
+services and look s like this:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>stop() {
+ KIND="SMB"
+ echo -n $"Shutting down $KIND services: "
+ killproc smbd
+ RETVAL=$?
+ echo
+ KIND="NMB"
+ echo -n $"Shutting down $KIND services: "
+ killproc nmbd
+ RETVAL2=$?
+ echo
+ KIND="Winbind"
+ echo -n $"Shutting down $KIND services: "
+ killproc winbindd
+ RETVAL3=$?
+ [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 -a $RETVAL3 -eq 0 ] &#38;&#38; rm -f /var/lock/subsys/smb
+ echo ""
+ return $RETVAL
+}</PRE
+></TD
+></TR
+></TABLE
+></P
><P
->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
-"<B
+>If you restart the <B
+CLASS="COMMAND"
+>smbd</B
+>, <B
CLASS="COMMAND"
->wins support = yes</B
->" option and the
-"<B
+>nmbd</B
+>,
+and <B
CLASS="COMMAND"
->wins server = &#62;name&#60;</B
->" option then
-nmbd will fail to start.</P
-><P
->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.</P
+>winbindd</B
+> daemons at this point, you
+should be able to connect to the samba server as a domain member just as
+if you were a local user.</P
></DIV
><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
+CLASS="SECT3"
+><HR><H3
+CLASS="SECT3"
><A
-NAME="AEN2649"
->15.6. Setting up Browsing in a WORKGROUP</A
-></H1
+NAME="AEN2189"
+>11.5.3.7. Configure Winbind and PAM</A
+></H3
><P
->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.</P
-><P
->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 :</P
+>If you have made it this far, you know that winbindd and samba 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
+> files? If not, do it now.)</P
><P
-><B
+>You will need a pam module to use winbindd 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 my RedHat system, this was the
+<TT
+CLASS="FILENAME"
+>/lib/security</TT
+> directory.</P
+><P
+><TT
+CLASS="PROMPT"
+>root#</TT
+> <B
CLASS="COMMAND"
-> domain master = yes</B
+>cp ../samba/source/nsswitch/pam_winbind.so /lib/security</B
></P
><P
->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 :</P
+>The <TT
+CLASS="FILENAME"
+>/etc/pam.d/samba</TT
+> file does not need to be changed. I
+just left this fileas it was:</P
><P
><TABLE
BORDER="0"
@@ -12856,25 +10332,33 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
-> domain master = yes
- local master = yes
- preferred master = yes
- os level = 65</PRE
+>auth required /lib/security/pam_stack.so service=system-auth
+account required /lib/security/pam_stack.so service=system-auth</PRE
></TD
></TR
></TABLE
></P
><P
->The domain master browser may be the same machine as the WINS
-server, if you require.</P
-><P
->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 :</P
+>The other services that I modified to allow the use of winbind
+as an authentication service were the normal login on the console (or a terminal
+session), telnet logins, and ftp 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"
@@ -12884,28 +10368,13 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
-> domain master = no
- local master = yes
- preferred master = yes
- os level = 65</PRE
+>enable = no</PRE
></TD
></TR
></TABLE
></P
><P
->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.</P
-><P
->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.</P
-><P
->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 :</P
+>to</P
><P
><TABLE
BORDER="0"
@@ -12915,36 +10384,36 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
-> domain master = no
- local master = no
- preferred master = no
- os level = 0</PRE
+>enable = yes</PRE
></TD
></TR
></TABLE
></P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2667"
->15.7. Setting up Browsing in a DOMAIN</A
-></H1
><P
->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&#62;1B&#60;) with WINS instead of the PDC.</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
->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 :</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"
@@ -12954,712 +10423,124 @@ WIDTH="100%"
><TD
><PRE
CLASS="PROGRAMLISTING"
-> domain master = no
- local master = yes
- preferred master = yes
- os level = 65</PRE
+>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
->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.</P
-><P
->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 :</P
-><P
-><B
-CLASS="COMMAND"
-> domain master = no
- local master = no
- preferred master = no
- os level = 0</B
-></P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2677"
->15.8. Forcing samba to be the master</A
-></H1
-><P
->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.</P
-><P
->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!)</P
-><P
->A "os level" of 2 would make it beat WfWg and Win95, but not NTAS. A
-NTAS domain controller uses level 32.</P
-><P
->The maximum os level is 255</P
-><P
->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.</P
-><P
->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.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2686"
->15.9. Making samba the domain master</A
-></H1
-><P
->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.</P
-><P
->Note that you should NOT set Samba to be the domain master for a
-workgroup that has the same name as an NT Domain.</P
-><P
->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.</P
-><P
->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.</P
-><P
->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:</P
-><P
-></P
-><OL
-TYPE="1"
-><LI
-><P
-> your local master browsers will be unable to find a domain master
- browser, as it will only be looking on the local subnet.
- </P
-></LI
-><LI
-><P
-> 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.
- </P
-></LI
-></OL
-><P
->If, however, both samba and your clients are using a WINS server, then:</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
-><OL
-TYPE="1"
-><LI
-><P
-> 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.
- </P
-></LI
-><LI
-><P
-> 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.
- </P
-></LI
-></OL
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2704"
->15.10. Note about broadcast addresses</A
-></H1
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2707"
->15.11. Multiple interfaces</A
-></H1
-><P
->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.</P
-></DIV
-></DIV
-><DIV
-CLASS="CHAPTER"
-><HR><H1
-><A
-NAME="SPEED"
->Chapter 16. Samba performance issues</A
-></H1
-><DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="AEN2725"
->16.1. Comparisons</A
-></H1
-><P
->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.</P
-><P
->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.</P
-><P
->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.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2731"
->16.2. Oplocks</A
-></H1
-><DIV
-CLASS="SECT2"
-><H2
-CLASS="SECT2"
-><A
-NAME="AEN2733"
->16.2.1. Overview</A
-></H2
-><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 agressively cache file
-data. With some oplock types the client may even cache file open/close
-operations. This can give enormous performance benefits.</P
><P
->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 :</P
-><P
-><B
+>In this case, I added the <B
CLASS="COMMAND"
->oplocks = False</B
-></P
-><P
->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.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN2741"
->16.2.2. Level2 Oplocks</A
-></H2
-><P
->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 :</P
-><P
-><B
+>auth sufficient /lib/security/pam_winbind.so</B
+>
+lines as before, but also added the <B
CLASS="COMMAND"
->level2 oplocks = true</B
-></P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT2"
-><HR><H2
-CLASS="SECT2"
-><A
-NAME="AEN2747"
->16.2.3. Old 'fake oplocks' option - deprecated</A
-></H2
-><P
->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.</P
-><P
->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.</P
-></DIV
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2751"
->16.3. Socket options</A
-></H1
-><P
->There are a number of socket options that can greatly affect the
-performance of a TCP based server like Samba.</P
-><P
->The socket options that Samba uses are settable both on the command
-line with the -O option, or in the smb.conf file.</P
-><P
->The "socket options" section of the smb.conf manual page describes how
-to set these and gives recommendations.</P
-><P
->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.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2758"
->16.4. Read size</A
-></H1
-><P
->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.</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
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2763"
->16.5. Max xmit</A
-></H1
-><P
->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.</P
-><P
->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.</P
-><P
->In most cases the default is the best option.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2768"
->16.6. Locking</A
-></H1
-><P
->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.</P
-><P
->The performance hit will probably be greater on NFS mounted
-filesystems, but could be quite high even on local disks.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2772"
->16.7. Share modes</A
-></H1
-><P
->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".</P
-><P
->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.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2777"
->16.8. Log level</A
-></H1
-><P
->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. </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2780"
->16.9. Wide lines</A
-></H1
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2783"
->16.10. Read raw</A
-></H1
-><P
->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.</P
-><P
->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. </P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2788"
->16.11. Write raw</A
-></H1
-><P
->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.</P
-><P
->Some machines may find "write raw" slower than normal write, in which
-case you may wish to change this option.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2792"
->16.12. Read prediction</A
-></H1
-><P
->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.</P
-><P
->This is disabled by default. You can enable it by using "read
-prediction = yes".</P
-><P
->Note that read prediction is only used on files that were opened read
-only.</P
-><P
->Read prediction should particularly help for those silly clients (such
-as "Write" under NT) which do lots of very small reads on a file.</P
-><P
->Samba will not read ahead more data than the amount specified in the
-"read size" option. It always reads ahead on 1k block boundaries.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2799"
->16.13. Memory mapping</A
-></H1
-><P
->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.</P
-><P
->To enable you you have to recompile Samba with the -DUSE_MMAP option
-on the FLAGS line of the Makefile.</P
-><P
->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".</P
+>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
></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2804"
->16.14. Slow Clients</A
-></H1
-><P
->One person has reported that setting the protocol to COREPLUS rather
-than LANMAN2 gave a dramatic speed improvement (from 10k/s to 150k/s).</P
-><P
->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.</P
></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2808"
->16.15. Slow Logins</A
-></H1
-><P
->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.</P
></DIV
><DIV
CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2811"
->16.16. Client tuning</A
+NAME="AEN2236"
+>11.6. Limitations</A
></H1
><P
->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.</P
-><P
->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.</P
-><P
->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.</P
-><P
->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.</P
-><P
->It probably depends a lot on your hardware, and the type of unix box
-you have at the other end of the link.</P
-><P
->Paul Cochrane has done some testing on client side tuning and come
-to the following conclusions:</P
-><P
->Install the W2setup.exe file from www.microsoft.com. This is an
-update for the winsock stack and utilities which improve performance.</P
-><P
->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:</P
+>Winbind has a number of limitations in its current
+ released version that we hope to overcome in future
+ releases:</P
><P
></P
-><OL
-TYPE="1"
-><LI
-><P
->MaxMTU Remove</P
-></LI
-><LI
-><P
->RWIN Remove</P
-></LI
-><LI
-><P
->MTUAutoDiscover Disable</P
-></LI
-><LI
-><P
->MTUBlackHoleDetect Disable</P
-></LI
+><UL
><LI
><P
->Time To Live Enabled</P
+>Winbind is currently only available for
+ the Linux operating system, although ports to other operating
+ systems are certainly possible. For such ports to be feasible,
+ we require the C library of the target operating system to
+ support the Name Service Switch and Pluggable Authentication
+ Modules systems. This is becoming more common as NSS and
+ PAM gain support among UNIX vendors.</P
></LI
><LI
><P
->Time To Live - HOPS 32</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
->NDI Cache Size 0</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
-></OL
-><P
->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!!!!!</P
-><P
->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.</P
-><P
->FIXME
-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</P
-><P
->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!!!!</P
-><P
->The updates mentioned in 1 and 2 brought up the transfer rates from
-just over 100kB/s in some clients.</P
-><P
->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.</P
-><P
->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.</P
+></UL
></DIV
><DIV
CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2843"
->16.17. My Results</A
+NAME="AEN2246"
+>11.7. Conclusion</A
></H1
><P
->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.</P
-><P
->I get 490k/s on reading a 8Mb file with copy.
-I get 441k/s writing the same file to the samba server.</P
-><P
->Of course, there's a lot more to benchmarks than 2 raw throughput
-figures, but it gives you a ballpark figure.</P
-><P
->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 ...</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
@@ -13667,23 +10548,23 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="OS2"
->Chapter 17. OS2 Client HOWTO</A
+>Chapter 12. OS2 Client HOWTO</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN2860"
->17.1. FAQs</A
+NAME="AEN2260"
+>12.1. FAQs</A
></H1
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
-NAME="AEN2862"
->17.1.1. How can I configure OS/2 Warp Connect or
+NAME="AEN2262"
+>12.1.1. How can I configure OS/2 Warp Connect or
OS/2 Warp 4 as a client for Samba?</A
></H2
><P
@@ -13741,8 +10622,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2877"
->17.1.2. How can I configure OS/2 Warp 3 (not Connect),
+NAME="AEN2277"
+>12.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
@@ -13794,8 +10675,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2886"
->17.1.3. Are there any other issues when OS/2 (any version)
+NAME="AEN2286"
+>12.1.3. Are there any other issues when OS/2 (any version)
is used as a client?</A
></H2
><P
@@ -13816,8 +10697,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2890"
->17.1.4. How do I get printer driver download working
+NAME="AEN2290"
+>12.1.4. How do I get printer driver download working
for OS/2 clients?</A
></H2
><P
@@ -13865,15 +10746,15 @@ CLASS="CHAPTER"
><HR><H1
><A
NAME="CVS-ACCESS"
->Chapter 18. HOWTO Access Samba source code via CVS</A
+>Chapter 13. HOWTO Access Samba source code via CVS</A
></H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
-NAME="AEN2906"
->18.1. Introduction</A
+NAME="AEN2306"
+>13.1. Introduction</A
></H1
><P
>Samba is developed in an open environment. Developers use CVS
@@ -13894,8 +10775,8 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN2911"
->18.2. CVS Access to samba.org</A
+NAME="AEN2311"
+>13.2. CVS Access to samba.org</A
></H1
><P
>The machine samba.org runs a publicly accessible CVS
@@ -13907,8 +10788,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2914"
->18.2.1. Access via CVSweb</A
+NAME="AEN2314"
+>13.2.1. Access via CVSweb</A
></H2
><P
>You can access the source code via your
@@ -13928,8 +10809,8 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN2919"
->18.2.2. Access via cvs</A
+NAME="AEN2319"
+>13.2.2. Access via cvs</A
></H2
><P
>You can also access the source code via a
@@ -14032,242 +10913,16 @@ CLASS="COMMAND"
></DIV
></DIV
></DIV
-><DIV
-CLASS="CHAPTER"
-><HR><H1
-><A
-NAME="BUGREPORT"
->Chapter 19. Reporting Bugs</A
-></H1
-><DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="AEN2954"
->19.1. Introduction</A
-></H1
-><P
->The email address for bug reports is samba@samba.org</P
-><P
->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.</P
-><P
->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. </P
-><P
->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.</P
-><P
->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/ </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2961"
->19.2. General info</A
-></H1
-><P
->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.</P
-><P
->Have you run through the <A
-HREF="Diagnosis.html"
-TARGET="_top"
->diagnosis</A
->?
-This is very important.</P
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2967"
->19.3. Debug levels</A
-></H1
-><P
->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.</P
-><P
->To set the debug level use <B
-CLASS="COMMAND"
->log level =</B
-> in your
-<TT
-CLASS="FILENAME"
->smb.conf</TT
->. 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:</P
-><P
-><TABLE
-BORDER="0"
-BGCOLOR="#E0E0E0"
-WIDTH="100%"
-><TR
-><TD
-><PRE
-CLASS="PROGRAMLISTING"
->log level = 10
-log file = /usr/local/samba/lib/log.%m
-include = /usr/local/samba/lib/smb.conf.%m</PRE
-></TD
-></TR
-></TABLE
-></P
-><P
->then create a file
-<TT
-CLASS="FILENAME"
->/usr/local/samba/lib/smb.conf.machine</TT
-> where
-"machine" is the name of the client you wish to debug. In that file
-put any smb.conf commands you want, for example
-<B
-CLASS="COMMAND"
->log level=</B
-> may be useful. This also allows you to
-experiment with different security systems, protocol levels etc on just
-one machine.</P
-><P
->The <TT
-CLASS="FILENAME"
->smb.conf</TT
-> entry <B
-CLASS="COMMAND"
->log level =</B
->
-is synonymous with the entry <B
-CLASS="COMMAND"
->debuglevel =</B
-> that has been
-used in older versions of Samba and is being retained for backwards
-compatibility of smb.conf files.</P
-><P
->As the <B
-CLASS="COMMAND"
->log level =</B
-> 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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2984"
->19.4. Internal errors</A
-></H1
-><P
->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)</P
-><P
->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.</P
-><P
->You should also detail how to reproduce the problem, if
-possible. Please make this reasonably detailed.</P
-><P
->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:</P
-><P
-><B
-CLASS="COMMAND"
->gdb smbd core</B
-></P
-><P
->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.</P
-><P
->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. </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2994"
->19.5. Attaching to a running process</A
-></H1
-><P
->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.</P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="AEN2997"
->19.6. Patches</A
-></H1
-><P
->The best sort of bug report is one that includes a fix! If you send us
-patches please use <B
-CLASS="COMMAND"
->diff -u</B
-> format if your version of
-diff supports it, otherwise use <B
-CLASS="COMMAND"
->diff -c4</B
->. Make sure
-your do the diff against a clean version of the source and let me know
-exactly what version you used. </P
-></DIV
-></DIV
><HR><H1
><A
-NAME="AEN3002"
+NAME="AEN2347"
>Index</A
></H1
><DL
><DT
>Primary Domain Controller,
<A
-HREF="x1741.htm"
+HREF="x1100.htm"
>Background</A
>
</DT
diff --git a/docs/htmldocs/Samba-LDAP-HOWTO.html b/docs/htmldocs/Samba-LDAP-HOWTO.html
index 21ebbfe7b0..3fb4e1df09 100644
--- a/docs/htmldocs/Samba-LDAP-HOWTO.html
+++ b/docs/htmldocs/Samba-LDAP-HOWTO.html
@@ -152,7 +152,7 @@ Identified (RID).</P
>As a result of these defeciencies, a more robust means of storing user attributes
used by smbd 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
+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
@@ -498,7 +498,7 @@ CLASS="REPLACEABLE"
ldap suffix = "ou=people,dc=samba,dc=org"
# generally the default ldap search filter is ok
- # ldap filter = "(&amp;(uid=%u)(objectclass=sambaAccount))"</PRE
+ # ldap filter = "(&#38;(uid=%u)(objectclass=sambaAccount))"</PRE
></P
></DIV
></DIV
diff --git a/docs/htmldocs/Samba-PDC-HOWTO.html b/docs/htmldocs/Samba-PDC-HOWTO.html
index ae4f545800..58f3989b4f 100644
--- a/docs/htmldocs/Samba-PDC-HOWTO.html
+++ b/docs/htmldocs/Samba-PDC-HOWTO.html
@@ -2124,7 +2124,7 @@ ALIGN="LEFT"
></TABLE
></DIV
><P
->The default logon path is \\%N\%U. NT Workstation will attempt to create
+>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".
diff --git a/docs/htmldocs/UNIX_INSTALL.html b/docs/htmldocs/UNIX_INSTALL.html
index 9946e7e64e..35b1d9b01b 100644
--- a/docs/htmldocs/UNIX_INSTALL.html
+++ b/docs/htmldocs/UNIX_INSTALL.html
@@ -478,7 +478,7 @@ CLASS="REPLACEABLE"
></TT
></P
><P
->You should get back a list of shares available on
+>Your 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
@@ -656,8 +656,8 @@ NAME="AEN166"
>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
+ need to use the -i &lt;scope&gt; option to nmbd, smbd, and
+ smbclient. All your PCs will need to have the same setting for
this to work. I do not recommend scope IDs.</P
></DIV
><DIV
@@ -778,13 +778,19 @@ NAME="AEN182"
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
+><P
+>You can disable share modes using "share modes = no".
+ This may be useful on a heavily loaded server as the share
+ modes code is very slow. See also the FAST_SHARE_MODES
+ option in the Makefile for a way to do full share modes
+ very fast using shared memory (if your OS supports it).</P
></DIV
><DIV
CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN191"
+NAME="AEN192"
>Mapping Usernames</A
></H2
><P
@@ -792,6 +798,21 @@ NAME="AEN191"
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="AEN195"
+>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
diff --git a/docs/htmldocs/rpcclient.1.html b/docs/htmldocs/rpcclient.1.html
index 9ffca61437..eaa864f109 100644
--- a/docs/htmldocs/rpcclient.1.html
+++ b/docs/htmldocs/rpcclient.1.html
@@ -37,12 +37,12 @@ NAME="AEN8"
><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] [-I destinationIP] {server}</P
+> [-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="AEN23"
+NAME="AEN22"
></A
><H2
>DESCRIPTION</H2
@@ -65,7 +65,7 @@ CLASS="COMMAND"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN29"
+NAME="AEN28"
></A
><H2
>OPTIONS</H2
@@ -151,35 +151,6 @@ CLASS="FILENAME"
</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
>-l|--logfile=logbasename</DT
><DD
><P
@@ -282,7 +253,7 @@ CLASS="COMMAND"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN101"
+NAME="AEN92"
></A
><H2
>COMMANDS</H2
@@ -676,7 +647,7 @@ CLASS="COMMAND"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN221"
+NAME="AEN212"
></A
><H2
>BUGS</H2
@@ -717,7 +688,7 @@ CLASS="COMMAND"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN231"
+NAME="AEN222"
></A
><H2
>VERSION</H2
@@ -728,7 +699,7 @@ NAME="AEN231"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN234"
+NAME="AEN225"
></A
><H2
>AUTHOR</H2
diff --git a/docs/htmldocs/smb.conf.5.html b/docs/htmldocs/smb.conf.5.html
index 6f0e88c4d3..d329c25d65 100644
--- a/docs/htmldocs/smb.conf.5.html
+++ b/docs/htmldocs/smb.conf.5.html
@@ -1465,11 +1465,11 @@ CLASS="PARAMETER"
><LI
><P
><A
-HREF="#LDAPSSL"
+HREF="#LDAPPORT"
><TT
CLASS="PARAMETER"
><I
->ldap ssl</I
+>ldap port</I
></TT
></A
></P
@@ -1477,11 +1477,11 @@ CLASS="PARAMETER"
><LI
><P
><A
-HREF="#LDAPSUFFIX"
+HREF="#LDAPSERVER"
><TT
CLASS="PARAMETER"
><I
->ldap suffix</I
+>ldap server</I
></TT
></A
></P
@@ -1489,11 +1489,11 @@ CLASS="PARAMETER"
><LI
><P
><A
-HREF="#LDAPUSERSUFFIX"
+HREF="#LDAPSSL"
><TT
CLASS="PARAMETER"
><I
->ldap suffix</I
+>ldap ssl</I
></TT
></A
></P
@@ -1501,7 +1501,7 @@ CLASS="PARAMETER"
><LI
><P
><A
-HREF="#LDAPMACHINESUFFIX"
+HREF="#LDAPSUFFIX"
><TT
CLASS="PARAMETER"
><I
@@ -2461,11 +2461,203 @@ CLASS="PARAMETER"
><LI
><P
><A
-HREF="#SPNEGO"
+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
->use spnego</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
@@ -2871,7 +3063,7 @@ CLASS="PARAMETER"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN927"
+NAME="AEN991"
></A
><H2
>COMPLETE LIST OF SERVICE PARAMETERS</H2
@@ -4350,7 +4542,7 @@ CLASS="PARAMETER"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN1419"
+NAME="AEN1483"
></A
><H2
>EXPLANATION OF EACH PARAMETER</H2
@@ -4883,28 +5075,6 @@ CLASS="COMMAND"
></DD
><DT
><A
-NAME="ADDGROUPSCRIPT"
-></A
->add group 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) when a new group is requested. It will expand any <TT
-CLASS="PARAMETER"
-><I
->%g</I
-></TT
-> to the group name passed. This script is only useful for installations using the Windows NT domain administration tools.
- </A
-> &#13;</P
-></DD
-><DT
-><A
NAME="ADMINUSERS"
></A
>admin users (S)</DT
@@ -6487,27 +6657,131 @@ NAME="DELETEUSERSCRIPT"
><DD
><P
>This is the full pathname to a script that will
- be run by <A
+ be run <EM
+>AS ROOT</EM
+> by <A
HREF="smbd.8.html"
TARGET="_top"
-><B
+> <B
CLASS="COMMAND"
>smbd(8)</B
></A
->
- when managing user's with remote RPC (NT) tools.
- </P
+> under special circumstances
+ described below.</P
><P
->This script is called when a remote client removes a user
- from the server, normally using 'User Manager for Domains' or
- <B
+>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"
->rpcclient</B
->.
- </P
+> 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
->This script should delete the given UNIX username.
- </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"
@@ -9161,14 +9435,26 @@ NAME="LDAPADMINDN"
>ldap admin dn (G)</DT
><DD
><P
-> The <TT
+>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 ldap server when retreiving
- user account information. The <TT
+ 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
@@ -9201,7 +9487,16 @@ NAME="LDAPFILTER"
>ldap filter (G)</DT
><DD
><P
->This parameter specifies the RFC 2254 compliant LDAP search filter.
+>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
@@ -9220,17 +9515,99 @@ CLASS="COMMAND"
></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</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 option is used to define whether or not Samba should
- use SSL when connecting to the ldap server
- This is <EM
+>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's previous SSL support which was enabled by specifying the
+ Samba SSL support which is enabled by specifying the
<B
CLASS="COMMAND"
>--with-ssl</B
@@ -9238,7 +9615,15 @@ CLASS="COMMAND"
CLASS="FILENAME"
>configure</TT
>
- script.
+ script (see <A
+HREF="#SSL"
+><TT
+CLASS="PARAMETER"
+><I
+>ssl</I
+></TT
+></A
+>).
</P
><P
> The <TT
@@ -9280,33 +9665,13 @@ NAME="LDAPSUFFIX"
>ldap suffix (G)</DT
><DD
><P
->Default : <EM
->none</EM
-></P
-></DD
-><DT
-><A
-NAME="LDAPUSERSUFFIX"
-></A
->ldap user suffix (G)</DT
-><DD
-><P
->It specifies where users are added to the tree.
- </P
-><P
->Default : <EM
->none</EM
-></P
-></DD
-><DT
-><A
-NAME="LDAPMACHINESUFFIX"
-></A
->ldap machine suffix (G)</DT
-><DD
-><P
->It specifies where machines should be
- added to the ldap tree.
+>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
@@ -9770,14 +10135,12 @@ NAME="LOGLEVEL"
>log level (G)</DT
><DD
><P
->The value of the parameter (a astring) allows
+>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 parameter has been
- extended since 2.2.x series, now it allow to specify the debug
- level for multiple debug classes. This is to give greater
+> file. This is to give greater
flexibility in the configuration of the system.</P
><P
>The default will be the log level specified on
@@ -9785,8 +10148,7 @@ CLASS="FILENAME"
><P
>Example: <B
CLASS="COMMAND"
->log level = 3 passdb:5 auth:10 winbind:2
- </B
+>log level = 3</B
></P
></DD
><DT
@@ -12696,41 +13058,23 @@ CLASS="COMMAND"
>Any characters after the (optional) second : are passed to the plugin
for its own processing</P
></LI
-><LI
-><P
-><B
-CLASS="COMMAND"
->unixsam</B
-> - Allows samba to map all (other) available unix users</P
-><P
->This backend uses the standard unix database for retrieving users. Users included
- in this pdb are NOT listed in samba user listings and users included in this pdb won't be
- able to login. The use of this backend is to always be able to display the owner of a file
- on the samba server - even when the user doesn't have a 'real' samba account in one of the
- other passdb backends.
- </P
-><P
->This backend should always be the last backend listed, since it contains all users in
- the unix passdb and might 'override' mappings if specified earlier. It's meant to only return
- accounts for users that aren't covered by the previous backends.</P
-></LI
></UL
>
</P
><P
>Default: <B
CLASS="COMMAND"
->passdb backend = smbpasswd unixsam</B
+>passdb backend = smbpasswd</B
></P
><P
>Example: <B
CLASS="COMMAND"
->passdb backend = tdbsam:/etc/samba/private/passdb.tdb smbpasswd:/etc/samba/smbpasswd unixsam</B
+>passdb backend = tdbsam:/etc/samba/private/passdb.tdb smbpasswd:/etc/samba/smbpasswd</B
></P
><P
>Example: <B
CLASS="COMMAND"
->passdb backend = ldapsam_nua:ldaps://ldap.example.com unixsam</B
+>passdb backend = ldapsam_nua:ldaps://ldap.example.com</B
></P
><P
>Example: <B
@@ -16323,15 +16667,606 @@ CLASS="COMMAND"
></DD
><DT
><A
-NAME="SPNEGO"
+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
->use spnego (G)</DT
+>ssl CA certFile (G)</DT
><DD
><P
-> This variable controls controls whether samba will try to use Simple and Protected NEGOciation (as specified by rfc2478) with WindowsXP and Windows2000sp2 clients to agree upon an authentication mechanism. As of samba 3.0alpha it must be set to "no" for these clients to join a samba domain controller. It can be set to "yes" to allow samba to participate in an AD domain controlled by a Windows2000 domain controller.</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: <EM
->use spnego = yes</EM
+>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
@@ -16795,9 +17730,9 @@ NAME="UNIXEXTENSIONS"
><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...
+ implments the CIFS UNIX extensions, as defined by HP. These
+ extensions enable CIFS to server UNIX clients to UNIX servers
+ better, and allow such things as symbolic links, hard links etc.
These extensions require a similarly enabled client, and are of
no current use to Windows clients.</P
><P
@@ -17365,12 +18300,6 @@ CLASS="CONSTANT"
connection is made to a Samba server. Sites may use this to record the
user connecting to a Samba share.</P
><P
->Due to the requirements of the utmp record, we
- are required to create a unique identifier for the
- incoming user. Enabling this option creates an n^2
- algorithm to find this number. This may impede
- performance on large installations. </P
-><P
>See also the <A
HREF="#UTMPDIRECTORY"
><TT
@@ -18317,7 +19246,7 @@ CLASS="COMMAND"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN5817"
+NAME="AEN6101"
></A
><H2
>WARNINGS</H2
@@ -18347,7 +19276,7 @@ TARGET="_top"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN5823"
+NAME="AEN6107"
></A
><H2
>VERSION</H2
@@ -18358,7 +19287,7 @@ NAME="AEN5823"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN5826"
+NAME="AEN6110"
></A
><H2
>SEE ALSO</H2
@@ -18437,7 +19366,7 @@ CLASS="COMMAND"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN5846"
+NAME="AEN6130"
></A
><H2
>AUTHOR</H2
diff --git a/docs/htmldocs/smbcontrol.1.html b/docs/htmldocs/smbcontrol.1.html
index 74c2854a86..5dc9854a84 100644
--- a/docs/htmldocs/smbcontrol.1.html
+++ b/docs/htmldocs/smbcontrol.1.html
@@ -170,7 +170,7 @@ CLASS="CONSTANT"
>,
or <TT
CLASS="CONSTANT"
->printnotify</TT
+>printer-notify</TT
>.</P
><P
>The <TT
@@ -246,68 +246,15 @@ CLASS="CONSTANT"
><P
>The <TT
CLASS="CONSTANT"
->printnotify</TT
+>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 the following arguments:
-
- <P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->queuepause printername</DT
-><DD
-><P
->Send a queue pause change notify
- message to the printer specified.</P
-></DD
-><DT
->queueresume printername</DT
-><DD
-><P
->Send a queue resume change notify
- message for the printer specified.</P
-></DD
-><DT
->jobpause printername unixjobid</DT
-><DD
-><P
->Send a job pause change notify
- message for the printer and unix jobid
- specified.</P
-></DD
-><DT
->jobresume printername unixjobid</DT
-><DD
-><P
->Send a job resume change notify
- message for the printer and unix jobid
- specified.</P
-></DD
-><DT
->jobdelete printername unixjobid</DT
-><DD
-><P
->Send a job delete change notify
- message for the printer and unix jobid
- specified.</P
-></DD
-></DL
-></DIV
->
-
- Note that this message only sends notification that an
- event has occured. It doesn't actually cause the
- event to happen.
-
+ 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
+>.</P
></DD
><DT
>parameters</DT
@@ -321,7 +268,7 @@ CLASS="CONSTANT"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN102"
+NAME="AEN81"
></A
><H2
>VERSION</H2
@@ -332,7 +279,7 @@ NAME="AEN102"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN105"
+NAME="AEN84"
></A
><H2
>SEE ALSO</H2
@@ -358,7 +305,7 @@ CLASS="COMMAND"
><DIV
CLASS="REFSECT1"
><A
-NAME="AEN112"
+NAME="AEN91"
></A
><H2
>AUTHOR</H2
diff --git a/docs/htmldocs/winbind.html b/docs/htmldocs/winbind.html
index 7d45b174dd..6063828222 100644
--- a/docs/htmldocs/winbind.html
+++ b/docs/htmldocs/winbind.html
@@ -410,20 +410,12 @@ for providing the HOWTO for this section.</P
>This HOWTO describes how to get winbind services up and running
to control access and authenticate users on your Linux box using
the winbind services which come with SAMBA 2.2.2.</P
-><P
->There is also some Solaris specific information in
-<TT
-CLASS="FILENAME"
->docs/textdocs/Solaris-Winbind-HOWTO.txt</TT
->.
-Future revisions of this document will incorporate that
-information.</P
><DIV
CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN78"
+NAME="AEN76"
>Introduction</A
></H2
><P
@@ -476,7 +468,7 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN91"
+NAME="AEN89"
>Requirements</A
></H2
><P
@@ -537,7 +529,7 @@ CLASS="SECT2"
><HR><H2
CLASS="SECT2"
><A
-NAME="AEN105"
+NAME="AEN103"
>Testing Things Out</A
></H2
><P
@@ -582,7 +574,7 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN116"
+NAME="AEN114"
>Configure and compile SAMBA</A
></H3
><P
@@ -648,7 +640,7 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN135"
+NAME="AEN133"
>Configure <TT
CLASS="FILENAME"
>nsswitch.conf</TT
@@ -680,30 +672,6 @@ CLASS="COMMAND"
>ln -s /lib/libnss_winbind.so /lib/libnss_winbind.so.2</B
></P
><P
->And, in the case of Sun solaris:</P
-><P
-><TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->ln -s /usr/lib/libnss_winbind.so /usr/lib/libnss_winbind.so.1</B
->
-<TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->ln -s /usr/lib/libnss_winbind.so /usr/lib/nss_winbind.so.1</B
->
-<TT
-CLASS="PROMPT"
->root#</TT
-> <B
-CLASS="COMMAND"
->ln -s /usr/lib/libnss_winbind.so /usr/lib/nss_winbind.so.2</B
-></P
-><P
>Now, as root you need to edit <TT
CLASS="FILENAME"
>/etc/nsswitch.conf</TT
@@ -753,7 +721,7 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN168"
+NAME="AEN158"
>Configure smb.conf</A
></H3
><P
@@ -828,7 +796,7 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN184"
+NAME="AEN174"
>Join the SAMBA server to the PDC domain</A
></H3
><P
@@ -874,7 +842,7 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN195"
+NAME="AEN185"
>Start up the winbindd daemon and test it!</A
></H3
><P
@@ -997,17 +965,12 @@ CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN231"
->Fix the init.d startup scripts</A
+NAME="AEN221"
+>Fix the <TT
+CLASS="FILENAME"
+>/etc/rc.d/init.d/smb</TT
+> startup files</A
></H3
-><DIV
-CLASS="SECT4"
-><H4
-CLASS="SECT4"
-><A
-NAME="AEN233"
->Linux</A
-></H4
><P
>The <B
CLASS="COMMAND"
@@ -1020,16 +983,15 @@ CLASS="COMMAND"
CLASS="COMMAND"
>nmbd</B
> daemons are running.
-To accomplish this task, you need to modify the startup scripts of your system. They are located at <TT
+To accomplish this task, you need to modify the <TT
CLASS="FILENAME"
>/etc/init.d/smb</TT
-> in RedHat and
+>
+script to add commands to invoke this daemon in the proper sequence. My
<TT
CLASS="FILENAME"
->/etc/init.d/samba</TT
-> in Debian.
-script to add commands to invoke this daemon in the proper sequence. My
-startup script starts up <B
+>/etc/init.d/smb</TT
+> file starts up <B
CLASS="COMMAND"
>smbd</B
>,
@@ -1095,86 +1057,6 @@ CLASS="PROGRAMLISTING"
return $RETVAL
}</PRE
></P
-></DIV
-><DIV
-CLASS="SECT4"
-><HR><H4
-CLASS="SECT4"
-><A
-NAME="AEN250"
->Solaris</A
-></H4
-><P
->On solaris, you need to modify the
-<TT
-CLASS="FILENAME"
->/etc/init.d/samba.server</TT
-> startup script. It usually
-only starts smbd and nmbd but should now start winbindd too. If you
-have samba installed in <TT
-CLASS="FILENAME"
->/usr/local/samba/bin</TT
->,
-the file could contains something like this:</P
-><P
-><PRE
-CLASS="PROGRAMLISTING"
->##
-## samba.server
-##
-
-if [ ! -d /usr/bin ]
-then # /usr not mounted
- exit
-fi
-
-killproc() { # kill the named process(es)
- pid=`/usr/bin/ps -e |
- /usr/bin/grep -w $1 |
- /usr/bin/sed -e 's/^ *//' -e 's/ .*//'`
- [ "$pid" != "" ] &#38;&#38; kill $pid
-}
-
-# Start/stop processes required for samba server
-
-case "$1" in
-
-'start')
-#
-# Edit these lines to suit your installation (paths, workgroup, host)
-#
-echo Starting SMBD
- /usr/local/samba/bin/smbd -D -s \
- /usr/local/samba/smb.conf
-
-echo Starting NMBD
- /usr/local/samba/bin/nmbd -D -l \
- /usr/local/samba/var/log -s /usr/local/samba/smb.conf
-
-echo Starting Winbind Daemon
- /usr/local/samba/bin/winbindd
- ;;
-
-'stop')
- killproc nmbd
- killproc smbd
- killproc winbindd
- ;;
-
-*)
- echo "Usage: /etc/init.d/samba.server { start | stop }"
- ;;
-esac</PRE
-></P
-></DIV
-><DIV
-CLASS="SECT4"
-><HR><H4
-CLASS="SECT4"
-><A
-NAME="AEN257"
->Restarting</A
-></H4
><P
>If you restart the <B
CLASS="COMMAND"
@@ -1190,13 +1072,12 @@ CLASS="COMMAND"
should be able to connect to the samba server as a domain member just as
if you were a local user.</P
></DIV
-></DIV
><DIV
CLASS="SECT3"
><HR><H3
CLASS="SECT3"
><A
-NAME="AEN263"
+NAME="AEN243"
>Configure Winbind and PAM</A
></H3
><P
@@ -1236,11 +1117,7 @@ your other pam security modules. On my RedHat system, this was the
<TT
CLASS="FILENAME"
>/lib/security</TT
-> directory. On Solaris, the pam security
-modules reside in <TT
-CLASS="FILENAME"
->/usr/lib/security</TT
->.</P
+> directory.</P
><P
><TT
CLASS="PROMPT"
@@ -1249,14 +1126,6 @@ CLASS="PROMPT"
CLASS="COMMAND"
>cp ../samba/source/nsswitch/pam_winbind.so /lib/security</B
></P
-><DIV
-CLASS="SECT4"
-><HR><H4
-CLASS="SECT4"
-><A
-NAME="AEN280"
->Linux/FreeBSD-specific PAM configuration</A
-></H4
><P
>The <TT
CLASS="FILENAME"
@@ -1378,91 +1247,6 @@ CLASS="COMMAND"
> line to get rid of annoying
double prompts for passwords.</P
></DIV
-><DIV
-CLASS="SECT4"
-><HR><H4
-CLASS="SECT4"
-><A
-NAME="AEN313"
->Solaris-specific configuration</A
-></H4
-><P
->The /etc/pam.conf needs to be changed. I changed this file so that my Domain
-users can logon both locally as well as telnet.The following are the changes
-that I made.You can customize the pam.conf file as per your requirements,but
-be sure of those changes because in the worst case it will leave your system
-nearly impossible to boot.</P
-><P
-><PRE
-CLASS="PROGRAMLISTING"
->#
-#ident "@(#)pam.conf 1.14 99/09/16 SMI"
-#
-# Copyright (c) 1996-1999, Sun Microsystems, Inc.
-# All Rights Reserved.
-#
-# PAM configuration
-#
-# Authentication management
-#
-login auth required /usr/lib/security/pam_winbind.so
-login auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-login auth required /usr/lib/security/$ISA/pam_dial_auth.so.1 try_first_pass
-#
-rlogin auth sufficient /usr/lib/security/pam_winbind.so
-rlogin auth sufficient /usr/lib/security/$ISA/pam_rhosts_auth.so.1
-rlogin auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-dtlogin auth sufficient /usr/lib/security/pam_winbind.so
-dtlogin auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-rsh auth required /usr/lib/security/$ISA/pam_rhosts_auth.so.1
-other auth sufficient /usr/lib/security/pam_winbind.so
-other auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-# Account management
-#
-login account sufficient /usr/lib/security/pam_winbind.so
-login account requisite /usr/lib/security/$ISA/pam_roles.so.1
-login account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-dtlogin account sufficient /usr/lib/security/pam_winbind.so
-dtlogin account requisite /usr/lib/security/$ISA/pam_roles.so.1
-dtlogin account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-other account sufficient /usr/lib/security/pam_winbind.so
-other account requisite /usr/lib/security/$ISA/pam_roles.so.1
-other account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Session management
-#
-other session required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Password management
-#
-#other password sufficient /usr/lib/security/pam_winbind.so
-other password required /usr/lib/security/$ISA/pam_unix.so.1
-dtsession auth required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Support for Kerberos V5 authentication (uncomment to use Kerberos)
-#
-#rlogin auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#login auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#dtlogin auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#other auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#dtlogin account optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other account optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other session optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other password optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass</PRE
-></P
-><P
->I also added a try_first_pass line after the winbind.so line to get rid of
-annoying double prompts for passwords.</P
-><P
->Now restart your Samba &#38; try connecting through your application that you
-configured in the pam.conf.</P
-></DIV
-></DIV
></DIV
></DIV
><DIV
@@ -1470,7 +1254,7 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN320"
+NAME="AEN290"
>Limitations</A
></H1
><P
@@ -1511,7 +1295,7 @@ CLASS="SECT1"
><HR><H1
CLASS="SECT1"
><A
-NAME="AEN330"
+NAME="AEN300"
>Conclusion</A
></H1
><P
diff --git a/docs/manpages/rpcclient.1 b/docs/manpages/rpcclient.1
index ea112a35ad..fd943e000e 100644
--- a/docs/manpages/rpcclient.1
+++ b/docs/manpages/rpcclient.1
@@ -3,12 +3,12 @@
.\" <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" "15 August 2002" "" ""
+.TH "RPCCLIENT" "1" "16 April 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 ] [ \fB-I destinationIP\fR ] \fBserver\fR
+\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 Sambasuite.
@@ -55,22 +55,6 @@ planning on submitting a bug report to the Samba team (see \fIBUGS.txt\fR).
\fB-h|--help\fR
Print a summary of command line options.
.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-l|--logfile=logbasename\fR
File name for log/debug files. The extension
\&'.client' will be appended. The log file is never removed
diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5
index caa27103db..692530334b 100644
--- a/docs/manpages/smb.conf.5
+++ b/docs/manpages/smb.conf.5
@@ -3,7 +3,7 @@
.\" <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" "15 August 2002" "" ""
+.TH "SMB.CONF" "5" "08 May 2002" "" ""
.SH NAME
smb.conf \- The configuration file for the Samba suite
.SH "SYNOPSIS"
@@ -657,13 +657,13 @@ each parameter for details. Note that some are synonyms.
\fIldap filter\fR
.TP 0.2i
\(bu
-\fIldap ssl\fR
+\fIldap port\fR
.TP 0.2i
\(bu
-\fIldap suffix\fR
+\fIldap server\fR
.TP 0.2i
\(bu
-\fIldap suffix\fR
+\fIldap ssl\fR
.TP 0.2i
\(bu
\fIldap suffix\fR
@@ -906,7 +906,55 @@ each parameter for details. Note that some are synonyms.
\fIsource environment\fR
.TP 0.2i
\(bu
-\fIuse spnego\fR
+\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
@@ -1558,11 +1606,6 @@ Default: \fBadd user script = <empty string>
Example: \fBadd user script = /usr/local/samba/bin/add_user
%u\fR
.TP
-\fBadd group script (G)\fR
-This is the full pathname to a script that will
-be run \fBAS ROOT\fR by smbd(8) when a new group is requested. It will expand any \fI%g\fR to the group name passed. This script is only useful for installations using the Windows NT domain administration tools.
-
-.TP
\fBadmin users (S)\fR
This is a list of users who will be granted
administrative privileges on the share. This means that they
@@ -2146,14 +2189,44 @@ Example: \fBdelete share command = /usr/local/bin/delshare\fR
.TP
\fBdelete user script (G)\fR
This is the full pathname to a script that will
-be run by \fBsmbd(8)\fR
-when managing user's with remote RPC (NT) tools.
+be run \fBAS ROOT\fR by \fBsmbd(8)\fRunder 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.
-This script is called when a remote client removes a user
-from the server, normally using 'User Manager for Domains' or
-\fBrpcclient\fR.
+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.
-This script should delete the given UNIX username.
+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
@@ -2671,7 +2744,7 @@ 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
+\fBforce directory 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 directory using the native NT security dialog box.
@@ -3229,9 +3302,14 @@ code paths.
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
+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)\fRman
@@ -3240,6 +3318,11 @@ 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
@@ -3247,13 +3330,43 @@ 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\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 ldap server
-This is \fBNOT\fR related to
-Samba's previous SSL support which was enabled by specifying the
+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.
+script (see \fIssl\fR).
The \fIldap ssl\fR can be set to one of three values:
(a) on - Always use SSL when contacting the
@@ -3265,16 +3378,10 @@ Never use SSL when querying the directory, or (c) start_tls
Default : \fBldap ssl = on\fR
.TP
\fBldap suffix (G)\fR
-Default : \fBnone\fR
-.TP
-\fBldap user suffix (G)\fR
-It specifies where users are added to the tree.
-
-Default : \fBnone\fR
-.TP
-\fBldap machine suffix (G)\fR
-It specifies where machines should be
-added to the ldap tree.
+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
@@ -3439,18 +3546,16 @@ 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 (a astring) allows
+The value of the parameter (an integer) allows
the debug level (logging level) to be specified in the
-\fIsmb.conf\fR file. This parameter has been
-extended since 2.2.x series, now it allow to specify the debug
-level for multiple debug classes. This is to give greater
+\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 passdb:5 auth:10 winbind:2
-\fR.TP
+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)
@@ -4685,27 +4790,14 @@ arbitary passdb backend from the .so specified as a compulsary argument.
Any characters after the (optional) second : are passed to the plugin
for its own processing
-.TP 0.2i
-\(bu
-\fBunixsam\fR - Allows samba to map all (other) available unix users
-
-This backend uses the standard unix database for retrieving users. Users included
-in this pdb are NOT listed in samba user listings and users included in this pdb won't be
-able to login. The use of this backend is to always be able to display the owner of a file
-on the samba server - even when the user doesn't have a 'real' samba account in one of the
-other passdb backends.
-
-This backend should always be the last backend listed, since it contains all users in
-the unix passdb and might 'override' mappings if specified earlier. It's meant to only return
-accounts for users that aren't covered by the previous backends.
.RE
.PP
-Default: \fBpassdb backend = smbpasswd unixsam\fR
+Default: \fBpassdb backend = smbpasswd\fR
-Example: \fBpassdb backend = tdbsam:/etc/samba/private/passdb.tdb smbpasswd:/etc/samba/smbpasswd unixsam\fR
+Example: \fBpassdb backend = tdbsam:/etc/samba/private/passdb.tdb smbpasswd:/etc/samba/smbpasswd\fR
-Example: \fBpassdb backend = ldapsam_nua:ldaps://ldap.example.com unixsam\fR
+Example: \fBpassdb backend = ldapsam_nua:ldaps://ldap.example.com\fR
Example: \fBpassdb backend = plugin:/usr/local/samba/lib/my_passdb.so:my_plugin_args tdbsam:/etc/samba/private/passdb.tdb\fR
.TP
@@ -6186,10 +6278,246 @@ Examples: \fBsource environment = |/etc/smb.conf.sh
Example: \fBsource environment =
/usr/local/smb_env_vars\fR
.TP
-\fBuse spnego (G)\fR
-This variable controls controls whether samba will try to use Simple and Protected NEGOciation (as specified by rfc2478) with WindowsXP and Windows2000sp2 clients to agree upon an authentication mechanism. As of samba 3.0alpha it must be set to "no" for these clients to join a samba domain controller. It can be set to "yes" to allow samba to participate in an AD domain controlled by a Windows2000 domain controller.
+\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)\fRif 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: \fBuse spnego = yes\fR
+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
@@ -6370,9 +6698,9 @@ 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...
+implments the CIFS UNIX extensions, as defined by HP. These
+extensions enable CIFS to server UNIX clients to UNIX servers
+better, and allow such things as symbolic links, hard links etc.
These extensions require a similarly enabled client, and are of
no current use to Windows clients.
@@ -6655,12 +6983,6 @@ 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.
-Due to the requirements of the utmp record, we
-are required to create a unique identifier for the
-incoming user. Enabling this option creates an n^2
-algorithm to find this number. This may impede
-performance on large installations.
-
See also the \fI utmp directory\fR parameter.
Default: \fButmp = no\fR
diff --git a/docs/manpages/smbcontrol.1 b/docs/manpages/smbcontrol.1
index d1479bff25..f3e6c843b5 100644
--- a/docs/manpages/smbcontrol.1
+++ b/docs/manpages/smbcontrol.1
@@ -3,7 +3,7 @@
.\" <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" "15 August 2002" "" ""
+.TH "SMBCONTROL" "1" "08 May 2002" "" ""
.SH NAME
smbcontrol \- send messages to smbd, nmbd or winbindd processes
.SH SYNOPSIS
@@ -47,7 +47,7 @@ One of: close-share,
debug,
force-election, ping
, profile, debuglevel, profilelevel,
-or printnotify.
+or printer-notify.
The close-share message-type sends a
message to smbd which will then close the client connections to
@@ -90,40 +90,11 @@ 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 printnotify message-type sends a
+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 the following arguments:
-.RS
-.TP
-\fBqueuepause printername\fR
-Send a queue pause change notify
-message to the printer specified.
-.TP
-\fBqueueresume printername\fR
-Send a queue resume change notify
-message for the printer specified.
-.TP
-\fBjobpause printername unixjobid\fR
-Send a job pause change notify
-message for the printer and unix jobid
-specified.
-.TP
-\fBjobresume printername unixjobid\fR
-Send a job resume change notify
-message for the printer and unix jobid
-specified.
-.TP
-\fBjobdelete printername unixjobid\fR
-Send a job delete change notify
-message for the printer and unix jobid
-specified.
-.RE
-.PP
-Note that this message only sends notification that an
-event has occured. It doesn't actually cause the
-event to happen.
-This message can only be sent to smbd.
+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
diff --git a/docs/textdocs/Samba-OpenSSL.txt b/docs/textdocs/Samba-OpenSSL.txt
new file mode 100644
index 0000000000..e1b54b1a03
--- /dev/null
+++ b/docs/textdocs/Samba-OpenSSL.txt
@@ -0,0 +1,405 @@
+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/Solaris-Winbind-HOWTO.txt b/docs/textdocs/Solaris-Winbind-HOWTO.txt
deleted file mode 100644
index a81bacf486..0000000000
--- a/docs/textdocs/Solaris-Winbind-HOWTO.txt
+++ /dev/null
@@ -1,361 +0,0 @@
-!==
-!== Solaris-Winbind-HOWTO.txt
-!==
-Contributors: Naag Mummaneni <getnag@rediffmail.com>
-Updated: May 2, 2002
-Status: Current
-
-Subject: Installing and Configuring Winbind on Solaris
-=============================================================================
-
-Installation and Configuration of Winbind on Solaris.
------------------------------------------------------
-
-This HOWTO describes how to get winbind services up and running to control
-access and authenticate users on your Solaris box using the winbind services
-which come with SAMBA 2.2.x latest CVS Checkout.Make sure you are using the
-latest Samba 2.2.x cvs checkout as other versions come with a lots of bugs
-regarding winbind .And even the Latest Samba Stable Release is also not an
-exception to this.
-
-Introduction
-------------
-
-This HOWTO describes the procedures used to get winbind up and running on a
-Solaris 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 for SAMBA services.
-
-Why should I to this?
-
-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.
-
-Who should be reading this document?
-
-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.
-
-Requirements
-------------
-
-If you have a samba configuration file that you are currently using... BACK
-IT UP! If your system already uses PAM, back up the /etc/pam.conf file ! If
-you haven't already made a boot disk, MAKEONE NOW! Messing with the pam
-configuration file can make it nearly impossible to log in to yourmachine.
-That's why you want to be able to boot back into your machine in single user
-mode and restore your /etc/pam.conf back to the original state they were in
-if you get frustrated with the way things are going. ;-) Please refer to the
-main SAMBA web page or, better yet, your closest SAMBA mirror site for
-instructions on downloading the source code of Samba 2.2.x from the SAMBA
-CVS repository. 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 should have at least
-the pam libraries resident on your system. Solaris 7/8 has its pam modules
-coming with the distribution itself.
-
-Testing Things Out
-------------------
-
-Before starting, it is probably best to kill off all the SAMBA related
-daemons running on your server. Kill off all smbd, nmbd, and winbindd
-processes that may be running.
-
-
-Configure and compile SAMBA
----------------------------
-
-The configuration and compilation of SAMBA is pretty straightforward. The
-first three steps may not be necessary depending upon whether or not you
-have previously built the Samba binaries.
-
-root# autoconf
-root# make clean
-root# rm config.cache
-root# ./configure --with-winbind --with-pam
-root# make
-root# make install
-
-This will, by default, install SAMBA in /usr/local/samba. See the main SAMBA
-documentation if you want to install SAMBA somewhere else. It will also
-build the winbindd executable and libraries.
-
-Configure nsswitch.conf and the winbind libraries
--------------------------------------------------
-
-The libraries needed to run the winbindd daemon through nsswitch need to be
-copied to their proper locations, so
-
-root# cp ../samba/source/nsswitch/libnss_winbind.so /usr/lib
-
-I also found it necessary to make the following symbolic links:
-
-root# ln -s /usr/lib/libnss_winbind.so /usr/lib/libnss_winbind.so.1
-root# ln -s /usr/lib/libnss_winbind.so /usr/lib/libnss_winbind.so.2
-root# ln -s /usr/lib/libnss_winbind.so /usr/lib/nss_winbind.so.1
-root# ln -s /usr/lib/libnss_winbind.so /usr/lib/nss_winbind.so.2
-
-Now, as root you need to edit /etc/nsswitch.conf to allow user and group
-entries to be visible from the winbindd daemon. My /etc/nsswitch.conf file
-look like this after editing:
-
- passwd: files winbind
- group: files winbind
-
-
-Configure smb.conf
-------------------
-
-Several parameters are needed in the smb.conf file to control the behavior
-of winbindd. Configure smb.conf These are described in more detail in the
-winbindd(8) man page. My smb.conf file was modified to include the following
-entries in the [global] section:
-
-[global]
- <...>
- # The previous documentation says to
- # as the "winbind seperator " directive also but
- # it is no longer supported.
-
- # use uids from 10000 to 20000 for domain users
- winbind uid = 10000-20000
-
- # use gids from 10000 to 20000 for domain groups
- winbind gid = 10000-20000
-
- # allow enumeration of winbind users and groups
- winbind enum users = yes
- winbind enum groups = yes
-
- # give winbind users a real shell (only needed if
- # they have telnet access)
- template homedir = /home/winnt/%D/%U
- template shell = /bin/bash
-
-
-Join the SAMBA server to the PDC domain
----------------------------------------
-
-Enter the following command to make the SAMBA server join the PDC domain,
-where DOMAIN is the name of your Windows domain and Administrator is a
-domain user who has administrative privileges in the domain.
-
-root# /usr/local/samba/bin/smbpasswd -j DOMAIN -r PDC -U Administrator
-
-The proper response to the command should be: "Joined the domain DOMAIN"
-where DOMAIN is your DOMAIN name.
-
-Start up the winbindd daemon and test it!
-
-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:
-
-root# /usr/local/samba/bin/winbindd
-
-I'm always paranoid and like to make sure the daemon is really running...
-
-root# ps -ae | grep winbindd
-
-This command should produce output like this, if the daemon is running
-
- 3025 ? 00:00:00 winbindd
-
-Now... for the real test, try to get some information about the users on
-your PDC
-
-root# /usr/local/samba/bin/wbinfo -u
-
-This should echo back a list of users on your Windows users on your PDC. For
-example, I get the following response:
-
-CEO\Administrator
-CEO\burdell
-CEO\Guest
-CEO\jt-ad
-CEO\krbtgt
-CEO\TsInternetUser
-
-root# /usr/local/samba/bin/wbinfo -g
-
-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
-
-The function 'getent' can now be used to get unified lists of both local and
-PDC users and groups. Try the following command:
-
-root# getent passwd
-
-You should get a list that looks like your /etc/passwd list followed by the domain users with their new
-uids, gids, home directories and default shells.
-
-The same thing can be done for groups with the command
-
-root# getent group
-
-Fix the /etc/rc.d/init.d/samba.server startup files The winbindd daemon
-needs to start up after the smbd and nmbd daemons are running. To accomplish
-this task, you need to modify the /etc/init.d/samba.server script to add
-commands to invoke this daemon in the proper sequence. My
-/etc/init.d/samba.server file starts up smbd, nmbd, and winbindd from the
-/usr/local/samba/bin directory directly.
-
-##
-## samba.server
-##
-
-if [ ! -d /usr/bin ]
-then # /usr not mounted
- exit
-fi
-
-killproc() { # kill the named process(es)
- pid=`/usr/bin/ps -e |
- /usr/bin/grep -w $1 |
- /usr/bin/sed -e 's/^ *//' -e 's/ .*//'`
- [ "$pid" != "" ] && kill $pid
-}
-
-# Start/stop processes required for samba server
-
-case "$1" in
-
-'start')
-#
-# Edit these lines to suit your installation (paths, workgroup, host)
-#
-echo Starting SMBD
- /usr/local/samba/bin/smbd -D -s \
- /usr/local/samba/smb.conf
-
-echo Starting NMBD
- /usr/local/samba/bin/nmbd -D -l \
- /usr/local/samba/var/log -s /usr/local/samba/smb.conf
-
-echo Starting Winbind Daemon
- /usr/local/samba/bin/winbindd
- ;;
-
-'stop')
- killproc nmbd
- killproc smbd
- killproc winbindd
- ;;
-
-*)
- echo "Usage: /etc/init.d/samba.server { start | stop }"
- ;;
-esac
-
-If you restart the smbd, nmbd, and winbindd daemons at this point, you
-should be able to connect to the samba server as a domain member just as if
-you were a local user.
-
-
-Configure Winbind and PAM
--------------------------
-
-If you have made it this far, you know that winbindd and samba are working
-together. If you want to use winbind to provide authentication for other
-services, keep reading. The pam configuration file need to be altered in
-this step. (Did you remember to make backups of your original /etc/pam.conf
-file? If not, do it now.) You will need a pam module to use winbindd with
-these other services. This module will be compiled in the ../source/nsswitch
-directory by default when we used ./configure --with-pam option.
-
-root# make nsswitch/pam_winbind.so
-
-from the ../source directory. The pam_winbind.so file should be copied to
-the location of your other pam security modules. On my Solaris 8, this was
-the /usr/lib/security directory.
-
-root# cp ../samba/source/nsswitch/pam_winbind.so /usr/lib/security
-
-The /etc/pam.conf need to be changed. I changed this file so that my Domain
-users can logon both locally as well as telnet.The following are the changes
-that I made.You can customize the pam.conf file as per your requirements,but
-be sure of those changes because in the worst case it will leave your system
-nearly impossible to boot.
-
-#
-#ident "@(#)pam.conf 1.14 99/09/16 SMI"
-#
-# Copyright (c) 1996-1999, Sun Microsystems, Inc.
-# All Rights Reserved.
-#
-# PAM configuration
-#
-# Authentication management
-#
-login auth required /usr/lib/security/pam_winbind.so
-login auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-login auth required /usr/lib/security/$ISA/pam_dial_auth.so.1 try_first_pass
-#
-rlogin auth sufficient /usr/lib/security/pam_winbind.so
-rlogin auth sufficient /usr/lib/security/$ISA/pam_rhosts_auth.so.1
-rlogin auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-dtlogin auth sufficient /usr/lib/security/pam_winbind.so
-dtlogin auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-rsh auth required /usr/lib/security/$ISA/pam_rhosts_auth.so.1
-other auth sufficient /usr/lib/security/pam_winbind.so
-other auth required /usr/lib/security/$ISA/pam_unix.so.1 try_first_pass
-#
-# Account management
-#
-login account sufficient /usr/lib/security/pam_winbind.so
-login account requisite /usr/lib/security/$ISA/pam_roles.so.1
-login account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-dtlogin account sufficient /usr/lib/security/pam_winbind.so
-dtlogin account requisite /usr/lib/security/$ISA/pam_roles.so.1
-dtlogin account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-other account sufficient /usr/lib/security/pam_winbind.so
-other account requisite /usr/lib/security/$ISA/pam_roles.so.1
-other account required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Session management
-#
-other session required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Password management
-#
-#other password sufficient /usr/lib/security/pam_winbind.so
-other password required /usr/lib/security/$ISA/pam_unix.so.1
-dtsession auth required /usr/lib/security/$ISA/pam_unix.so.1
-#
-# Support for Kerberos V5 authentication (uncomment to use Kerberos)
-#
-#rlogin auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#login auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#dtlogin auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#other auth optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-#dtlogin account optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other account optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other session optional /usr/lib/security/$ISA/pam_krb5.so.1
-#other password optional /usr/lib/security/$ISA/pam_krb5.so.1 try_first_pass
-
-I also added a try_first_pass line after the winbind.so line to get rid of
-annoying double prompts for passwords.
-
-Now restart your Samba & try connecting through your application that you
-configured in the pam.conf.
-
-
-
-!==
-!== end of Solaris-Winbind-HOWTO.txt
-!==
diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema
index 61dface0a2..be088c7403 100644
--- a/examples/LDAP/samba.schema
+++ b/examples/LDAP/samba.schema
@@ -119,20 +119,8 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
# 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 ))
-
-## 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'
+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 $
diff --git a/examples/VFS/Makefile b/examples/VFS/Makefile
new file mode 100644
index 0000000000..f93cd0cb2d
--- /dev/null
+++ b/examples/VFS/Makefile
@@ -0,0 +1,37 @@
+#
+# Makefile for samba-vfs examples
+#
+#
+
+# Variables
+
+CC = gcc
+LIBTOOL = libtool
+
+SAMBA_SRC = ../../source
+SAMBA_INCL = ../../source/include
+POPT_INCL = ../../source/popt
+UBIQX_SRC = ../../source/ubiqx
+SMBWR_SRC = ../../source/smbwrapper
+KRB5_SRC = /usr/kerberos/include
+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(POPT_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(KRB5_SRC) -Wall -g
+VFS_OBJS = audit.so skel.so recycle.so
+
+# Default target
+
+default: $(VFS_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 \
+ $(VFS_OBJS) $(VFS_OBJS:.so=.o) $(VFS_OBJS:.so=.lo)
diff --git a/examples/VFS/audit.c b/examples/VFS/audit.c
index 92b78c1c32..aad483c295 100644
--- a/examples/VFS/audit.c
+++ b/examples/VFS/audit.c
@@ -3,7 +3,6 @@
* facility.
*
* Copyright (C) Tim Potter, 1999-2000
- * 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
@@ -48,79 +47,134 @@
/* Function prototypes */
-static int audit_connect(struct connection_struct *conn, const char *svc, const char *user);
-static void audit_disconnect(struct connection_struct *conn);
-static DIR *audit_opendir(struct connection_struct *conn, const char *fname);
-static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode);
-static int audit_rmdir(struct connection_struct *conn, const char *path);
-static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode);
-static int audit_close(struct files_struct *fsp, int fd);
-static int audit_rename(struct connection_struct *conn, const char *old, const char *new);
-static int audit_unlink(struct connection_struct *conn, const char *path);
-static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode);
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode);
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode);
+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 */
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *audit_handle;
+extern struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static vfs_op_tuple audit_ops[] = {
+struct vfs_ops audit_ops = {
/* Disk operations */
- {audit_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
- {audit_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
+ audit_connect,
+ audit_disconnect,
+ NULL, /* disk free */
/* Directory operations */
- {audit_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
- {audit_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
- {audit_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
+ audit_opendir,
+ NULL, /* readdir */
+ audit_mkdir,
+ audit_rmdir,
+ NULL, /* closedir */
/* File operations */
- {audit_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
- {audit_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
- {audit_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
- {audit_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
- {audit_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
- {audit_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
- {audit_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
-
- /* Finish VFS operations definition */
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ audit_open,
+ audit_close,
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* lseek */
+ 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 vfs_op_tuple array back to SAMBA. */
+/* VFS initialisation function. Return initialised vfs_ops structure
+ back to SAMBA. */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
+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(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- audit_handle = vfs_handle;
+ 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;
-}
-
-/* VFS finalization function. */
-void vfs_done(connection_struct *conn)
-{
- syslog(SYSLOG_PRIORITY, "VFS_DONE: vfs module unloaded\n");
+ return &audit_ops;
}
/* Implementation of vfs_ops. Pass everything on to the default
operation but log event first. */
-static int audit_connect(struct connection_struct *conn, const char *svc, const char *user)
+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);
@@ -128,13 +182,13 @@ static int audit_connect(struct connection_struct *conn, const char *svc, const
return default_vfs_ops.connect(conn, svc, user);
}
-static void audit_disconnect(struct connection_struct *conn)
+void audit_disconnect(struct connection_struct *conn)
{
syslog(SYSLOG_PRIORITY, "disconnected\n");
default_vfs_ops.disconnect(conn);
}
-static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
+DIR *audit_opendir(struct connection_struct *conn, const char *fname)
{
DIR *result = default_vfs_ops.opendir(conn, fname);
@@ -146,7 +200,7 @@ static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
return result;
}
-static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
+int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
{
int result = default_vfs_ops.mkdir(conn, path, mode);
@@ -158,7 +212,7 @@ static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t
return result;
}
-static int audit_rmdir(struct connection_struct *conn, const char *path)
+int audit_rmdir(struct connection_struct *conn, const char *path)
{
int result = default_vfs_ops.rmdir(conn, path);
@@ -170,7 +224,7 @@ static int audit_rmdir(struct connection_struct *conn, const char *path)
return result;
}
-static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode)
+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);
@@ -183,7 +237,7 @@ static int audit_open(struct connection_struct *conn, const char *fname, int fla
return result;
}
-static int audit_close(struct files_struct *fsp, int fd)
+int audit_close(struct files_struct *fsp, int fd)
{
int result = default_vfs_ops.close(fsp, fd);
@@ -195,7 +249,7 @@ static int audit_close(struct files_struct *fsp, int fd)
return result;
}
-static int audit_rename(struct connection_struct *conn, const char *old, const char *new)
+int audit_rename(struct connection_struct *conn, const char *old, const char *new)
{
int result = default_vfs_ops.rename(conn, old, new);
@@ -207,7 +261,7 @@ static int audit_rename(struct connection_struct *conn, const char *old, const c
return result;
}
-static int audit_unlink(struct connection_struct *conn, const char *path)
+int audit_unlink(struct connection_struct *conn, const char *path)
{
int result = default_vfs_ops.unlink(conn, path);
@@ -219,7 +273,7 @@ static int audit_unlink(struct connection_struct *conn, const char *path)
return result;
}
-static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode)
+int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode)
{
int result = default_vfs_ops.chmod(conn, path, mode);
@@ -231,7 +285,7 @@ static int audit_chmod(struct connection_struct *conn, const char *path, mode_t
return result;
}
-static int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode)
+int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode)
{
int result = default_vfs_ops.chmod_acl(conn, path, mode);
@@ -243,7 +297,7 @@ static int audit_chmod_acl(struct connection_struct *conn, const char *path, mod
return result;
}
-static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
+int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
{
int result = default_vfs_ops.fchmod(fsp, fd, mode);
@@ -255,7 +309,7 @@ static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
return result;
}
-static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
+int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
{
int result = default_vfs_ops.fchmod_acl(fsp, fd, mode);
diff --git a/examples/VFS/block/Makefile b/examples/VFS/block/Makefile
new file mode 100644
index 0000000000..44b08681d6
--- /dev/null
+++ b/examples/VFS/block/Makefile
@@ -0,0 +1,37 @@
+#
+# Makefile for samba-vfs examples
+#
+#
+
+# Variables
+
+CC = gcc
+LIBTOOL = libtool
+
+SAMBA_SRC = ../../../source
+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
+
+
+VFS_OBJS = block.so
+
+# Default target
+
+default: $(VFS_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 \
+ $(VFS_OBJS) $(VFS_OBJS:.so=.o) $(VFS_OBJS:.so=.lo)
diff --git a/examples/VFS/block/block.c b/examples/VFS/block/block.c
index 9478b75f0f..f83ab6e07e 100644
--- a/examples/VFS/block/block.c
+++ b/examples/VFS/block/block.c
@@ -3,7 +3,6 @@
* Block access from links to dev mount points specified in PARAMCONF file
*
* Copyright (C) Ronald Kuetemeier, 2001
- * 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
@@ -48,29 +47,93 @@
-static DIR *block_opendir(connection_struct *conn, char *fname);
-static int block_connect(connection_struct *conn, const char *service, const char *user);
-static void block_disconnect(connection_struct *conn);
+DIR *block_opendir(struct connection_struct *conn, char *fname);
+int block_connect(struct connection_struct *conn, const char *service, const char *user);
+void block_disconnect(struct connection_struct *conn);
-static struct smb_vfs_handle_struct *block_handle;
/* VFS operations */
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
+extern struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static vfs_op_tuple block_vfs_ops[] = {
+struct vfs_ops execute_vfs_ops = {
/* Disk operations */
- {block_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {block_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
+ block_connect,
+ block_disconnect,
+ NULL, /* disk free */
/* Directory operations */
- {block_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ block_opendir,
+ NULL, /* readdir */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* closedir */
+
+ /* File operations */
+
+ NULL, /* open */
+ NULL, /* close */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* lseek */
+ 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 */
};
@@ -82,13 +145,13 @@ extern BOOL pm_process(char *FileName, BOOL (*sfunc)(char *), BOOL(*pfunc)(char
//functions
-static BOOL enter_pblock_mount(char *dir);
-static BOOL get_section(char *sect);
-static BOOL get_parameter_value(char *param, char *value);
-static BOOL load_param(void);
-static BOOL search(struct stat *stat_buf);
-static BOOL dir_search(char *link, char *dir);
-static BOOL enter_pblock_dir(char *dir);
+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, char *dir);
+BOOL enter_pblock_dir(char *dir);
@@ -113,7 +176,7 @@ static struct block_dir *pblock_dir = NULL;
* Load the conf file into a table
*/
-static BOOL load_param(void)
+BOOL load_param(void)
{
if ((pm_process(PARAMCONF,&get_section,&get_parameter_value)) == TRUE)
@@ -131,7 +194,7 @@ static BOOL load_param(void)
*
*/
-static BOOL enter_pblock_mount(char *dir)
+BOOL enter_pblock_mount(char *dir)
{
struct stat stat_buf;
static struct block_dir *tmp_pblock;
@@ -179,7 +242,7 @@ static BOOL enter_pblock_mount(char *dir)
*
*/
-static BOOL enter_pblock_dir(char *dir)
+BOOL enter_pblock_dir(char *dir)
{
static struct block_dir *tmp_pblock;
@@ -222,7 +285,7 @@ static BOOL enter_pblock_dir(char *dir)
* Function callback for config section names
*/
-static BOOL get_section(char *sect)
+BOOL get_section(char *sect)
{
return TRUE;
}
@@ -234,7 +297,7 @@ static BOOL get_section(char *sect)
*
*/
-static BOOL get_parameter_value(char *param, char *value)
+BOOL get_parameter_value(char *param, char *value)
{
int i = 0, maxargs = sizeof(params) / sizeof(char *);
@@ -264,25 +327,24 @@ static BOOL get_parameter_value(char *param, char *value)
-/* VFS initialisation function. Return initialised vfs_op_tuple array
+/* VFS initialisation function. Return initialised vfs_ops structure
back to SAMBA. */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
+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(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- block_handle = vfs_handle;
-
- return block_vfs_ops;
-}
+ 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;
-/* VFS finalization function. */
-void vfs_done(connection_struct *conn)
-{
+ memcpy(&execute_vfs_ops, &tmp_ops, sizeof(struct vfs_ops));
+ return(&execute_vfs_ops);
}
@@ -290,7 +352,7 @@ void vfs_done(connection_struct *conn)
* VFS connect and param file loading
*/
-static int block_connect(connection_struct *conn, const char *service, const char *user)
+int block_connect(struct connection_struct *conn, char *service, char *user)
{
if((load_param()) == FALSE)
{
@@ -310,7 +372,7 @@ static int block_connect(connection_struct *conn, const char *service, const cha
*/
-static void block_disconnect(struct connection_struct *conn)
+void block_disconnect(struct connection_struct *conn)
{
struct block_dir *tmp_pblock = (pblock_mountp == NULL ? pblock_dir : pblock_mountp);
@@ -341,7 +403,7 @@ static void block_disconnect(struct connection_struct *conn)
* VFS opendir
*/
-static DIR *block_opendir(struct connection_struct *conn, char *fname)
+DIR *block_opendir(struct connection_struct *conn, char *fname)
{
char *dir_name = NULL;
@@ -375,7 +437,7 @@ static DIR *block_opendir(struct connection_struct *conn, char *fname)
* Find mount point to block in list
*/
-static BOOL search(struct stat *stat_buf)
+BOOL search(struct stat *stat_buf)
{
struct block_dir *tmp_pblock = pblock_mountp;
@@ -397,7 +459,7 @@ static BOOL search(struct stat *stat_buf)
* Find dir in list to block id the starting point is link from a share
*/
-static BOOL dir_search(char *link, char *dir)
+BOOL dir_search(char *link, char *dir)
{
char buf[PATH_MAX +1], *ext_path;
int len = 0;
diff --git a/examples/VFS/recycle.c b/examples/VFS/recycle.c
index ed89e59abf..6a1c98ce54 100644
--- a/examples/VFS/recycle.c
+++ b/examples/VFS/recycle.c
@@ -4,7 +4,6 @@
*
* 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,
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,67 +40,139 @@
/* VFS operations */
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *recycle_handle;
+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);
-static vfs_op_tuple recycle_ops[] = {
-
+struct vfs_ops recycle_ops = {
+
/* Disk operations */
- {recycle_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_OPAQUE},
- {recycle_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_OPAQUE},
+ recycle_connect, /* connect */
+ recycle_disconnect, /* disconnect */
+ NULL, /* disk free */
+
+ /* Directory operations */
+
+ NULL, /* opendir */
+ NULL, /* readdir */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* closedir */
/* File operations */
-
- {recycle_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_OPAQUE},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+
+ NULL, /* open */
+ NULL, /* close */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* lseek */
+ 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 */
};
-/* VFS initialisation function. Return initialised vfs_op_tuple array back to SAMBA. */
+/* VFS initialisation function. Return initialised vfs_ops structure
+ back to SAMBA. */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
+struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops)
{
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- /* Remember vfs_id for storing private information at connect */
- recycle_handle = vfs_handle;
-
- return recycle_ops;
-}
+ struct vfs_ops tmp_ops;
-/* VFS finalization function. */
-void vfs_done(connection_struct *conn)
-{
- DEBUG(3,("vfs_done_recycle: called for connection %p\n",conn));
+ *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)
{
+ pstring opts_str;
fstring recycle_bin;
+ char *p;
DEBUG(3,("recycle_connect: called for service %s as user %s\n", service, user));
- fstrcpy(recycle_bin, (const char *)lp_parm_string(lp_servicename(SNUM(conn)),"vfs","recycle bin"));
- if (!*recycle_bin) {
- DEBUG(3,("recycle_connect: No options listed (vfs:recycle bin).\n" ));
+ pstrcpy(opts_str, (const char *)lp_vfs_options(SNUM(conn)));
+ if (!*opts_str) {
+ DEBUG(3,("recycle_connect: No options listed (%s).\n", lp_vfs_options(SNUM(conn)) ));
return 0; /* No options. */
}
- DEBUG(3,("recycle_connect: recycle name is %s\n", recycle_bin ));
+ p = opts_str;
+ if (next_token(&p,recycle_bin,"=",sizeof(recycle_bin))) {
+ if (!strequal("recycle", recycle_bin)) {
+ DEBUG(3,("recycle_connect: option %s is not recycle\n", recycle_bin ));
+ return -1;
+ }
+ }
+
+ if (!next_token(&p,recycle_bin," \n",sizeof(recycle_bin))) {
+ DEBUG(3,("recycle_connect: no option after recycle=\n"));
+ return -1;
+ }
+
+ DEBUG(10,("recycle_connect: recycle name is %s\n", recycle_bin ));
- recycle_handle->data = (void *)strdup(recycle_bin);
+ conn->vfs_private = (void *)strdup(recycle_bin);
return 0;
}
static void recycle_disconnect(struct connection_struct *conn)
{
- SAFE_FREE(recycle_handle->data);
+ SAFE_FREE(conn->vfs_private);
}
static BOOL recycle_XXX_exist(connection_struct *conn, const char *dname, BOOL isdir)
@@ -154,8 +225,8 @@ static int recycle_unlink(connection_struct *conn, const char *inname)
*recycle_bin = '\0';
pstrcpy(fname, inname);
- if (recycle_handle->data)
- fstrcpy(recycle_bin, (const char *)recycle_handle->data);
+ if (conn->vfs_private)
+ fstrcpy(recycle_bin, (const char *)conn->vfs_private);
if(!*recycle_bin) {
DEBUG(3, ("recycle bin: share parameter not set, purging %s...\n", fname));
diff --git a/examples/VFS/skel.c b/examples/VFS/skel.c
index b937682822..bb5486e690 100644
--- a/examples/VFS/skel.c
+++ b/examples/VFS/skel.c
@@ -3,7 +3,6 @@
* calls to disk functions.
*
* Copyright (C) Tim Potter, 1999-2000
- * 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
@@ -39,8 +38,8 @@
#include <includes.h>
#include <vfs.h>
-static struct vfs_ops default_vfs_ops; /* For passthrough operation */
-static struct smb_vfs_handle_struct *skel_handle; /* use skel_handle->data for storing per-instance private data */
+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)
{
@@ -350,110 +349,172 @@ static int skel_sys_acl_free_qualifier(struct connection_struct *conn, void *qua
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.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 */
-static vfs_op_tuple skel_ops[] = {
+struct vfs_ops skel_ops = {
/* Disk operations */
- {skel_connect, SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {skel_disconnect, SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {skel_disk_free, SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_TRANSPARENT},
+ skel_connect,
+ skel_disconnect,
+ skel_disk_free,
/* Directory operations */
- {skel_opendir, SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {skel_readdir, SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
- {skel_mkdir, SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
- {skel_rmdir, SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
- {skel_closedir, SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_TRANSPARENT},
+ skel_opendir,
+ skel_readdir,
+ skel_mkdir,
+ skel_rmdir,
+ skel_closedir,
/* File operations */
- {skel_open, SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
- {skel_close, SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_TRANSPARENT},
- {skel_read, SMB_VFS_OP_READ, SMB_VFS_LAYER_TRANSPARENT},
- {skel_write, SMB_VFS_OP_WRITE, SMB_VFS_LAYER_TRANSPARENT},
- {skel_lseek, SMB_VFS_OP_LSEEK, SMB_VFS_LAYER_TRANSPARENT},
- {skel_rename, SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {skel_fsync, SMB_VFS_OP_FSYNC, SMB_VFS_LAYER_TRANSPARENT},
- {skel_stat, SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
- {skel_fstat, SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {skel_lstat, SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {skel_unlink, SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {skel_chmod, SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {skel_fchmod, SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {skel_chown, SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {skel_fchown, SMB_VFS_OP_FCHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {skel_chdir, SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT},
- {skel_getwd, SMB_VFS_OP_GETWD, SMB_VFS_LAYER_TRANSPARENT},
- {skel_utime, SMB_VFS_OP_UTIME, SMB_VFS_LAYER_TRANSPARENT},
- {skel_ftruncate, SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_TRANSPARENT},
- {skel_lock, SMB_VFS_OP_LOCK, SMB_VFS_LAYER_TRANSPARENT},
- {skel_symlink, SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT},
- {skel_readlink, SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
- {skel_link, SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT},
- {skel_mknod, SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT},
- {skel_realpath, SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
+ skel_open,
+ skel_close,
+ skel_read,
+ skel_write,
+ skel_lseek,
+ 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, SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {skel_get_nt_acl, SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {skel_fset_nt_acl, SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {skel_set_nt_acl, SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
+ skel_fget_nt_acl,
+ skel_get_nt_acl,
+ skel_fset_nt_acl,
+ skel_set_nt_acl,
/* POSIX ACL operations */
- {skel_chmod_acl, SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {skel_fchmod_acl, SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- {skel_sys_acl_get_entry, SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_get_tag_type, SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_get_permset, SMB_VFS_OP_SYS_ACL_GET_PERMSET, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_get_qualifier, SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_get_file, SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_get_fd, SMB_VFS_OP_SYS_ACL_GET_FD, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_clear_perms, SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_add_perm, SMB_VFS_OP_SYS_ACL_ADD_PERM, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_to_text, SMB_VFS_OP_SYS_ACL_TO_TEXT, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_init, SMB_VFS_OP_SYS_ACL_INIT, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_create_entry, SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_set_tag_type, SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_set_qualifier, SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_set_permset, SMB_VFS_OP_SYS_ACL_SET_PERMSET, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_valid, SMB_VFS_OP_SYS_ACL_VALID, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_set_file, SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_set_fd, SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_delete_def_file, SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_get_perm, SMB_VFS_OP_SYS_ACL_GET_PERM, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_free_text, SMB_VFS_OP_SYS_ACL_FREE_TEXT, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_free_acl, SMB_VFS_OP_SYS_ACL_FREE_ACL, SMB_VFS_LAYER_TRANSPARENT},
- {skel_sys_acl_free_qualifier, SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, SMB_VFS_LAYER_TRANSPARENT},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ 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
};
-
-/* VFS initialisation - return initialized vfs_op_tuple array back to Samba */
-
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle)
-{
- DEBUG(3, ("Initialising default vfs hooks\n"));
-
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
- memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
-
- /* Remember vfs_handle for further allocation and referencing of private
- information in vfs_handle->data
- */
- skel_handle = vfs_handle;
- return skel_ops;
-}
-
-/* VFS finalization function */
-void vfs_done(connection_struct *conn)
-{
- DEBUG(3, ("Finalizing default vfs hooks\n"));
-}
diff --git a/examples/pdb/README b/examples/pdb/README
index 561473129b..a212604792 100644
--- a/examples/pdb/README
+++ b/examples/pdb/README
@@ -1,9 +1,5 @@
README for Samba Password Database (PDB) examples
====================================================
-8-8-2002 Jelmer Vernooij <jelmer@samba.org>
-
-Added mysql and xml modules. See README in xml/ and mysql/ for details.
-
21-6-2002 Stefan (metze) Metzmacher <metze@metzemix.de>
I have added an interface versioning.
diff --git a/examples/pdb/pdb_test.c b/examples/pdb/pdb_test.c
index b46fe24bd6..d2722d2e03 100644
--- a/examples/pdb/pdb_test.c
+++ b/examples/pdb/pdb_test.c
@@ -71,7 +71,7 @@ static BOOL testsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user,
Search by sid
**************************************************************************/
-static BOOL testsam_getsampwsid (struct pdb_methods *methods, SAM_ACCOUNT *user, const DOM_SID *sid)
+static BOOL testsam_getsampwsid (struct pdb_methods *methods, SAM_ACCOUNT *user, DOM_SID sid)
{
DEBUG(10, ("testsam_getsampwsid called\n"));
return False;
@@ -81,7 +81,7 @@ static BOOL testsam_getsampwsid (struct pdb_methods *methods, SAM_ACCOUNT *user,
Delete a SAM_ACCOUNT
****************************************************************************/
-static BOOL testsam_delete_sam_account(struct pdb_methods *methods, SAM_ACCOUNT *sam_pass)
+static BOOL testsam_delete_sam_account(struct pdb_methods *methods, const SAM_ACCOUNT *sam_pass)
{
DEBUG(10, ("testsam_delete_sam_account called\n"));
return False;
@@ -91,7 +91,7 @@ static BOOL testsam_delete_sam_account(struct pdb_methods *methods, SAM_ACCOUNT
Modifies an existing SAM_ACCOUNT
****************************************************************************/
-static BOOL testsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
+static BOOL testsam_update_sam_account (struct pdb_methods *methods, const SAM_ACCOUNT *newpwd)
{
DEBUG(10, ("testsam_update_sam_account called\n"));
return False;
@@ -101,7 +101,7 @@ static BOOL testsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT
Adds an existing SAM_ACCOUNT
****************************************************************************/
-static BOOL testsam_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
+static BOOL testsam_add_sam_account (struct pdb_methods *methods, const SAM_ACCOUNT *newpwd)
{
DEBUG(10, ("testsam_add_sam_account called\n"));
return False;
diff --git a/packaging/Caldera/OpenLinux/samba3.spec.tmpl b/packaging/Caldera/OpenLinux/samba3.spec.tmpl
index 701dd35073..23ebcd879e 100644
--- a/packaging/Caldera/OpenLinux/samba3.spec.tmpl
+++ b/packaging/Caldera/OpenLinux/samba3.spec.tmpl
@@ -254,15 +254,15 @@ CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
make all nsswitch/libnss_wins.so nsswitch/libnss_winbind.so torture nsswitch/pam_winbind.so everything
(cd tdb; make tdbdump tdbtest tdbtorture tdbtool)
-#cd ../examples/VFS
-#CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
-# --prefix='$(DESTDIR)/usr' \
-# --localstatedir='$(DESTDIR)/var' \
-# --libdir='$(DESTDIR)%{EtcSamba}' \
-# --sbindir='$(DESTDIR)/usr/sbin'
-#make
-#cd block
-#make
+cd ../examples/VFS
+CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="-s" ./configure \
+ --prefix='$(DESTDIR)/usr' \
+ --localstatedir='$(DESTDIR)/var' \
+ --libdir='$(DESTDIR)%{EtcSamba}' \
+ --sbindir='$(DESTDIR)/usr/sbin'
+make
+cd block
+make
%Install
%{mkDESTDIR}
@@ -305,10 +305,10 @@ do
install -m 755 source/tdb/$i $DESTDIR/usr/sbin
done
# Add VFS Modules
-#for i in audit.so recycle.so block/block.so
-#do
-# install -m755 $i $DESTDIR/lib/samba
-#done
+for i in audit.so recycle.so block/block.so
+do
+ install -m755 $i $DESTDIR/lib/samba
+done
#mv $DESTDIR/usr/bin/{make,add,conv}* $DESTDIR/usr/sbin
diff --git a/source3/CodingSuggestions b/source3/CodingSuggestions
index e5f366ec71..eda2bee6d0 100644
--- a/source3/CodingSuggestions
+++ b/source3/CodingSuggestions
@@ -25,11 +25,7 @@ documents are:
http://www.fsf.org/prep/standards_toc.html
but note that coding style in Samba varies due to the many different
-programmers who have contributed.
-
-The indent utility can be used to format C files in the general
-samba coding style. The arguments you should give to indent are:
--bad -bap -br -ce -cdw -nbc -brs -bbb -nbc -npsl
+programmers who have contributed.
Following are some considerations you should use when adding new code to
Samba. First and foremost remember that:
@@ -141,20 +137,12 @@ Here are some other suggestions:
to and maintain your code. If it would be hard for someone else to
maintain then do it another way.
-26) Always keep the declaration of a function on one line. The autoprototyper
- doesn't catch declarations spread over multiple lines.
- Use:
-static char foo(int bar)
- and not:
-static char
-foo(int bar)
-
The suggestions above are simply that, suggestions, but the information may
help in reducing the routine rework done on new code. The preceeding list
is expected to change routinely as new support routines and macros are
added.
Written by Steve French, with contributions from Simo Sorce, Andrew
-Bartlett, Tim Potter, Martin Pool and Jelmer Vernooij.
+Bartlett, Tim Potter and Martin Pool.
**/
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 2db6d55011..46cbfcd210 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1,4 +1,4 @@
-#########################################################################
+##########################################################################
# Makefile.in for Samba - rewritten for autoconf support
# Copyright Andrew Tridgell 1992-1998
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
@@ -52,7 +52,7 @@ INSTALLPERMS = 0755
# set these to where to find various files
# These can be overridden by command line switches (see smbd(8))
# or in smb.conf (see smb.conf(5))
-LOGFILEBASE = @logfilebase@
+LOGFILEBASE = $(VARDIR)
CONFIGFILE = $(LIBDIR)/smb.conf
LMHOSTSFILE = $(LIBDIR)/lmhosts
DRIVERFILE = $(LIBDIR)/printers.def
@@ -110,7 +110,7 @@ TORTURE_PROGS = bin/smbtorture bin/msgtest bin/masktest bin/locktest \
SHLIBS = @LIBSMBCLIENT@
SCRIPTS = $(srcdir)/script/smbtar $(srcdir)/script/addtosmbpass $(srcdir)/script/convert_smbpasswd \
- $(builddir)/script/findsmb
+ $(srcdir)/script/findsmb
QUOTAOBJS=@QUOTAOBJS@
@@ -129,7 +129,7 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.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/util_sid.o lib/util_uuid.o \
+ lib/util_str.o lib/util_sid.o \
lib/util_unistr.o lib/util_file.o lib/data_blob.o \
lib/util.o lib/util_sock.o lib/util_sec.o \
lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
@@ -138,9 +138,7 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
lib/md5.o lib/hmacmd5.o lib/iconv.o lib/smbpasswd.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/popt_common.o $(TDB_OBJ)
-
-LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
+ $(TDB_OBJ)
READLINE_OBJ = lib/readline.o
@@ -168,21 +166,17 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \
libsmb/passchange.o libsmb/unexpected.o libsmb/doserr.o \
- libsmb/namecache.o $(RPC_PARSE_OBJ1)
+ $(RPC_PARSE_OBJ1)
-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
+LIBMSRPC_OBJ = libsmb/cli_lsarpc.o libsmb/cli_samr.o \
+ libsmb/cli_netlogon.o libsmb/cli_srvsvc.o libsmb/cli_wkssvc.o \
+ libsmb/cli_dfs.o libsmb/cli_reg.o \
+ rpc_client/cli_pipe.o libsmb/cli_spoolss.o libsmb/cli_spoolss_notify.o
LIBMSRPC_SERVER_OBJ = libsmb/trust_passwd.o
LIBMSRPC_PICOBJ = $(LIBMSRPC_OBJ:.o=.po)
-REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
- registry/reg_db.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 \
@@ -190,7 +184,7 @@ RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_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 $(REGISTRY_OBJ)
+ rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
# this includes only the low level parse code, not stuff
# that requires knowledge of security contexts
@@ -267,8 +261,7 @@ SMBD_OBJ = $(SMBD_OBJ1) $(MSDFS_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) \
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
- $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ)
+ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ)
NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
@@ -285,7 +278,7 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(PROFILE_OBJ) $(LIB_OBJ) $(SECRETS_OBJ)
+ $(PROFILE_OBJ) $(LIB_OBJ)
WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \
wrepld/partners.o
@@ -445,8 +438,7 @@ PROTO_OBJ = $(SMBD_OBJ1) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \
$(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \
$(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
$(QUOTAOBJS) $(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \
- $(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ)
+ $(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ)
NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) \
$(LIB_OBJ) $(NSSWINS_OBJ)
@@ -459,9 +451,16 @@ LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.po)
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 \
- libsmb/smbencrypt.o libsmb/smbdes.o libsmb/nterr.o \
- $(PARAM_OBJ) $(LIB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(SECRETS_OBJ) $(UBIQX_OBJ)
+ 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/util_file.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 \
+ $(PARAM_OBJ) $(TDB_OBJ) $(PASSDB_OBJ)
PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.po)
diff --git a/source3/acconfig.h b/source3/acconfig.h
index 274bc4aaad..3962b18554 100644
--- a/source3/acconfig.h
+++ b/source3/acconfig.h
@@ -218,6 +218,3 @@
#ifndef _GNU_SOURCE
#undef _GNU_SOURCE
#endif
-
-#undef LDAP_SET_REBIND_PROC_ARGS
-
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index d43afc71e1..4f7a5c24a0 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -395,33 +395,33 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
{
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);
+ auth_method_list = str_list_make("guest sam ntdomain");
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);
+ auth_method_list = str_list_make("guest sam smbserver");
break;
case SEC_USER:
if (lp_encrypted_passwords()) {
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
- auth_method_list = str_list_make("guest sam", NULL);
+ auth_method_list = str_list_make("guest sam");
} else {
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
- auth_method_list = str_list_make("guest unix", NULL);
+ auth_method_list = str_list_make("guest unix");
}
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);
+ auth_method_list = str_list_make("guest sam");
} else {
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
- auth_method_list = str_list_make("guest unix", NULL);
+ auth_method_list = str_list_make("guest unix");
}
break;
case SEC_ADS:
DEBUG(5,("Making default auth method list for security=ADS\n"));
- auth_method_list = str_list_make("guest sam ads winbind ntdomain", NULL);
+ auth_method_list = str_list_make("guest sam ads ntdomain");
break;
default:
DEBUG(5,("Unknown auth method!\n"));
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index d48cec5b29..3352c5f9c8 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -29,88 +29,6 @@ BOOL global_machine_password_needs_changing = False;
extern pstring global_myname;
extern userdom_struct current_user_info;
-
-/*
- resolve the name of a DC in ways appropriate for an ADS domain mode
- an ADS domain may not have Netbios enabled at all, so this is
- quite different from the RPC case
- Note that we ignore the 'server' parameter here. That has the effect of using
- the 'ADS server' smb.conf parameter, which is what we really want anyway
- */
-static NTSTATUS ads_resolve_dc(fstring remote_machine,
- struct in_addr *dest_ip)
-{
- ADS_STRUCT *ads;
- ads = ads_init_simple();
- if (!ads) {
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- DEBUG(4,("ads_resolve_dc: realm=%s\n", ads->config.realm));
-
- ads->auth.no_bind = 1;
-
-#ifdef HAVE_ADS
- /* a full ads_connect() is actually overkill, as we don't srictly need
- to do the SASL auth in order to get the info we need, but libads
- doesn't offer a better way right now */
- ads_connect(ads);
-#endif
-
- fstrcpy(remote_machine, ads->config.ldap_server_name);
- strupper(remote_machine);
- *dest_ip = ads->ldap_ip;
- ads_destroy(&ads);
-
- if (!*remote_machine || is_zero_ip(*dest_ip)) {
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- DEBUG(4,("ads_resolve_dc: using server='%s' IP=%s\n",
- remote_machine, inet_ntoa(*dest_ip)));
-
- return NT_STATUS_OK;
-}
-
-/*
- resolve the name of a DC in ways appropriate for RPC domain mode
- this relies on the server supporting netbios and port 137 not being
- firewalled
- */
-static NTSTATUS rpc_resolve_dc(const char *server,
- fstring remote_machine,
- struct in_addr *dest_ip)
-{
- if (is_ipaddress(server)) {
- struct in_addr to_ip = *interpret_addr2(server);
-
- /* we need to know the machines netbios name - this is a lousy
- way to find it, but until we have a RPC call that does this
- it will have to do */
- if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
- DEBUG(2, ("connect_to_domain_password_server: Can't "
- "resolve name for IP %s\n", server));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- *dest_ip = to_ip;
- return NT_STATUS_OK;
- }
-
- fstrcpy(remote_machine, server);
- 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));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- DEBUG(4,("rpc_resolve_dc: using server='%s' IP=%s\n",
- remote_machine, inet_ntoa(*dest_ip)));
-
- return NT_STATUS_OK;
-}
-
/**
* Connect to a remote server for domain security authenticaion.
*
@@ -132,22 +50,37 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
fstring remote_machine;
NTSTATUS result;
- if (lp_security() == SEC_ADS) {
- result = ads_resolve_dc(remote_machine, &dest_ip);
+ 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));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
+ DEBUG(0, ("connect_to_domain_password_server: Can't "
+ "resolve name for IP %s\n", server));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
} else {
- result = rpc_resolve_dc(server, remote_machine, &dest_ip);
+ fstrcpy(remote_machine, server);
}
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(2,("connect_to_domain_password_server: unable to resolve DC: %s\n",
- nt_errstr(result)));
- return result;
- }
+ standard_sub_basic(current_user_info.smb_name, 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));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
if (ismyip(dest_ip)) {
DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n",
remote_machine));
- return NT_STATUS_NO_LOGON_SERVERS;
+ return NT_STATUS_UNSUCCESSFUL;
}
/* TODO: Send a SAMLOGON request to determine whether this is a valid
@@ -165,11 +98,11 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
*/
if (!grab_server_mutex(server))
- return NT_STATUS_NO_LOGON_SERVERS;
+ return NT_STATUS_UNSUCCESSFUL;
/* Attempt connection */
- result = cli_full_connection(cli, global_myname, remote_machine,
- &dest_ip, 0, "IPC$", "IPC", "", "", "",0);
+ result = cli_full_connection(cli, global_myname, server,
+ &dest_ip, 0, "IPC$", "IPC", "", "", "", 0);
if (!NT_STATUS_IS_OK(result)) {
release_server_mutex();
@@ -196,7 +129,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
cli_ulogoff(*cli);
cli_shutdown(*cli);
release_server_mutex();
- return NT_STATUS_NO_LOGON_SERVERS;
+ return NT_STATUS_UNSUCCESSFUL;
}
snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as);
@@ -206,7 +139,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
return NT_STATUS_NO_MEMORY;
}
- result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd);
+ result = new_cli_nt_setup_creds(*cli, sec_chan, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \
@@ -241,10 +174,10 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli,
*/
if (is_zero_ip(*ip))
- return NT_STATUS_NO_LOGON_SERVERS;
+ return NT_STATUS_UNSUCCESSFUL;
if (!lookup_dc_name(global_myname, domain, ip, dc_name))
- return NT_STATUS_NO_LOGON_SERVERS;
+ return NT_STATUS_UNSUCCESSFUL;
return connect_to_domain_password_server(cli, dc_name, setup_creds_as, sec_chan, trust_passwd);
}
@@ -263,7 +196,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
struct in_addr *ip_list = NULL;
int count = 0;
int i;
- NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
time_t time_now = time(NULL);
BOOL use_pdc_only = False;
@@ -279,7 +212,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
use_pdc_only = True;
if (!get_dc_list(use_pdc_only, domain, &ip_list, &count))
- return NT_STATUS_NO_LOGON_SERVERS;
+ return NT_STATUS_UNSUCCESSFUL;
/*
* Firstly try and contact a PDC/BDC who has the same
@@ -355,7 +288,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
fstring remote_machine;
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
- NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
/*
* At this point, smb_apasswd points to the lanman response to
@@ -367,7 +300,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
while (!NT_STATUS_IS_OK(nt_status) &&
next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
- if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) {
+ if(strequal(remote_machine, "*")) {
nt_status = find_connect_pdc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time);
} else {
nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as, sec_chan, trust_passwd);
@@ -570,7 +503,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
#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);
+ E_md4hash((uchar *)trust_password, trust_md4_password);
SAFE_FREE(trust_password);
#if 0
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index 155370546a..76579150ce 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -107,7 +107,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
memcpy(client_response, ntv2_response.data, sizeof(client_response));
ntv2_owf_gen(part_passwd, user, domain, kr);
- SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption);
+ SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, (char *)value_from_encryption);
if (user_sess_key != NULL)
{
SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key);
@@ -232,26 +232,11 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
{
return NT_STATUS_OK;
} else {
- if (lp_ntlm_auth()) {
- /* Apparently NT accepts NT responses in the LM feild
- - I think this is related to Win9X pass-though authenticaion
- */
- DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM feild\n"));
- if (smb_pwd_check_ntlmv1(user_info->lm_resp,
- nt_pw, auth_context->challenge,
- user_sess_key))
- {
- return NT_STATUS_OK;
- } else {
- DEBUG(3,("sam_password_ok: NT MD4 password in LM feild failed for user %s\n",pdb_get_username(sampass)));
- return NT_STATUS_WRONG_PASSWORD;
- }
- }
DEBUG(4,("sam_password_ok: LM password check failed for user %s\n",pdb_get_username(sampass)));
return NT_STATUS_WRONG_PASSWORD;
}
}
-
+
/* Should not be reached, but if they send nothing... */
DEBUG(3,("sam_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass)));
return NT_STATUS_WRONG_PASSWORD;
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index f914d91871..3ade220c0f 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -25,6 +25,7 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
+extern fstring remote_machine;
extern pstring global_myname;
/****************************************************************************
@@ -393,7 +394,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
ret = make_user_info_map(user_info, smb_name,
client_domain,
- get_remote_machine_name(),
+ remote_machine,
local_lm_blob,
local_nt_blob,
plaintext_password,
@@ -428,7 +429,7 @@ BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
return make_user_info_map(user_info, smb_name,
client_domain,
- get_remote_machine_name(),
+ remote_machine,
lm_resp,
nt_resp,
no_plaintext_blob,
diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c
index 5bdccd39f3..671e198bf5 100644
--- a/source3/auth/auth_winbind.c
+++ b/source3/auth/auth_winbind.c
@@ -32,30 +32,6 @@ NSS_STATUS winbindd_request(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
-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(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_append_data(&ps, info3_ndr, len);
- ps.data_offset = 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 */
@@ -68,11 +44,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
+ struct passwd *pw;
NTSTATUS nt_status;
- NET_USER_INFO_3 info3;
if (!user_info) {
- return NT_STATUS_INVALID_PARAMETER;
+ return NT_STATUS_UNSUCCESSFUL;
}
if (!auth_context) {
@@ -86,14 +62,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- request.data.auth_crap.flags = WINBIND_PAM_INFO3_NDR;
+ snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user),
+ "%s\\%s", user_info->domain.str, user_info->smb_name.str);
- 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);
+ fstrcpy(request.data.auth_crap.user, user_info->smb_name.str);
+ fstrcpy(request.data.auth_crap.domain, user_info->domain.str);
memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
@@ -103,28 +76,27 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
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);
+ sizeof(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);
+ request.data.auth_crap.lm_resp_len);
result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
- 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);
+ if (result == NSS_STATUS_SUCCESS) {
+
+ pw = Get_Pwnam(user_info->internal_username.str);
+
+ if (pw) {
+ if (make_server_info_pw(server_info, pw)) {
+ nt_status = NT_STATUS_OK;
+ } else {
+ nt_status = NT_STATUS_NO_MEMORY;
}
+ } else {
+ nt_status = NT_STATUS_NO_SUCH_USER;
}
- } else if (NT_STATUS_IS_OK(nt_status)) {
- nt_status = NT_STATUS_UNSUCCESSFUL;
+ } else {
+ nt_status = NT_STATUS_LOGON_FAILURE;
}
return nt_status;
diff --git a/source3/bin/.cvsignore b/source3/bin/.cvsignore
index c87d15fdb4..c152d8918a 100644
--- a/source3/bin/.cvsignore
+++ b/source3/bin/.cvsignore
@@ -10,7 +10,6 @@ msgtest
net
nmbd
nmblookup
-nsstest
pdbedit
rpcclient
samsync
@@ -19,7 +18,6 @@ smbcacls
smbclient
smbcontrol
smbd
-smbfilter
smbgroupedit
smbmnt
smbmount
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index c453cfbb54..43b0ef44bc 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -492,7 +492,7 @@ static int strslashcmp(char *s1, char *s2)
if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0;
/* check for s1 is an "initial" string of s2 */
- if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0;
+ if (*s2 == '/' || *s2 == '\\') return 0;
return *s1-*s2;
}
diff --git a/source3/client/smbmount.c b/source3/client/smbmount.c
index 0db990e8bd..ad050063ec 100644
--- a/source3/client/smbmount.c
+++ b/source3/client/smbmount.c
@@ -29,6 +29,7 @@
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;
@@ -376,7 +377,7 @@ 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"); /* sneaky ... */
+ pstrcpy(remote_machine, "smbmount"); /* sneaky ... */
setup_logging("mount.smbfs", False);
append_log = True;
reopen_logs();
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index ecb5c311c5..b78d9d22a8 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -282,17 +282,20 @@ smb_connect(char *workgroup, /* I - Workgroup */
get_myname(myname);
nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????",
- username, workgroup, password, 0);
+ username, lp_workgroup(), password, 0);
- if (!NT_STATUS_IS_OK(nt_status)) {
+ if (NT_STATUS_IS_OK(nt_status)) {
+ return c;
+ } else {
fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status));
return NULL;
}
- /*
- * Return the new connection...
- */
-
+
+ /*
+ * Return the new connection...
+ */
+
return (c);
}
diff --git a/source3/configure b/source3/configure
index 06694c8e64..be0e78133a 100755
--- a/source3/configure
+++ b/source3/configure
@@ -5932,7 +5932,7 @@ else
fi
done
-for ac_func in syslog vsyslog getgrouplist
+for ac_func in syslog vsyslog
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:5939: checking for $ac_func" >&5
@@ -13763,10 +13763,6 @@ WINBIND_PAM_PROGS=""
if test x"$HAVE_WINBIND" = x"yes"; then
echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define WITH_WINBIND 1
-EOF
-
WINBIND_TARGETS="bin/wbinfo"
WINBIND_STARGETS="bin/winbindd"
@@ -13781,6 +13777,58 @@ else
fi
+# Check for FreeBSD problem with getgroups
+# It returns EGID too many times in the list of groups
+# and causes a security problem
+echo $ac_n "checking whether or not getgroups returns EGID too many times""... $ac_c" 1>&6
+echo "configure:13785: checking whether or not getgroups returns EGID too many times" >&5
+if eval "test \"`echo '$''{'samba_cv_have_getgroups_too_many_egids'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ samba_cv_have_getgroups_too_many_egids=cross
+else
+ cat > conftest.$ac_ext <<EOF
+#line 13793 "configure"
+#include "confdefs.h"
+
+#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);
+}
+EOF
+if { (eval echo configure:13809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ samba_cv_have_getgroups_too_many_egids=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ samba_cv_have_getgroups_too_many_egids=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_have_getgroups_too_many_egids" 1>&6
+if test x"$samba_cv_have_getgroups_too_many_egids" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETGROUPS_TOO_MANY_EGIDS 1
+EOF
+
+fi
+
+
+
# Substitution time!
@@ -13800,20 +13848,20 @@ fi
# [#include <pwd.h>])
echo $ac_n "checking whether struct passwd has pw_comment""... $ac_c" 1>&6
-echo "configure:13804: checking whether struct passwd has pw_comment" >&5
+echo "configure:13852: checking whether struct passwd has pw_comment" >&5
if eval "test \"`echo '$''{'samba_cv_passwd_pw_comment'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 13810 "configure"
+#line 13858 "configure"
#include "confdefs.h"
#include <pwd.h>
int main() {
struct passwd p; p.pw_comment;
; return 0; }
EOF
-if { (eval echo configure:13817: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:13865: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_passwd_pw_comment=yes
else
@@ -13838,20 +13886,20 @@ fi
# [#include <pwd.h>])
echo $ac_n "checking whether struct passwd has pw_age""... $ac_c" 1>&6
-echo "configure:13842: checking whether struct passwd has pw_age" >&5
+echo "configure:13890: checking whether struct passwd has pw_age" >&5
if eval "test \"`echo '$''{'samba_cv_passwd_pw_age'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 13848 "configure"
+#line 13896 "configure"
#include "confdefs.h"
#include <pwd.h>
int main() {
struct passwd p; p.pw_age;
; return 0; }
EOF
-if { (eval echo configure:13855: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:13903: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_passwd_pw_age=yes
else
@@ -13890,7 +13938,7 @@ fi
if test x"$INCLUDED_POPT" != x"yes"; then
echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
-echo "configure:13894: checking for poptGetContext in -lpopt" >&5
+echo "configure:13942: checking for poptGetContext in -lpopt" >&5
ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -13898,7 +13946,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lpopt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 13902 "configure"
+#line 13950 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -13909,7 +13957,7 @@ int main() {
poptGetContext()
; return 0; }
EOF
-if { (eval echo configure:13913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -13933,9 +13981,9 @@ fi
fi
echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6
-echo "configure:13937: checking whether to use included popt" >&5
+echo "configure:13985: checking whether to use included popt" >&5
if test x"$INCLUDED_POPT" = x"yes"; then
- echo "$ac_t""yes" 1>&6
+ echo "$ac_t""$srcdir/popt" 1>&6
BUILD_POPT='$(POPT_OBJS)'
FLAGS1="-I$srcdir/popt"
else
@@ -13956,16 +14004,16 @@ fi
# final configure stuff
echo $ac_n "checking configure summary""... $ac_c" 1>&6
-echo "configure:13960: checking configure summary" >&5
+echo "configure:14008: checking configure summary" >&5
if test "$cross_compiling" = yes; then
echo "configure: warning: cannot run when cross-compiling" 1>&2
else
cat > conftest.$ac_ext <<EOF
-#line 13965 "configure"
+#line 14013 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/summary.c"
EOF
-if { (eval echo configure:13969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:14017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
echo "$ac_t""yes" 1>&6
else
@@ -14082,7 +14130,7 @@ done
ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
-trap 'rm -fr `echo "include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+trap 'rm -fr `echo "include/stamp-h Makefile script/findsmb include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
@@ -14216,7 +14264,7 @@ EOF
cat >> $CONFIG_STATUS <<EOF
-CONFIG_FILES=\${CONFIG_FILES-"include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile"}
+CONFIG_FILES=\${CONFIG_FILES-"include/stamp-h Makefile script/findsmb"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
diff --git a/source3/configure.in b/source3/configure.in
index db34c266c5..915c91e585 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -746,7 +746,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 getgrouplist)
+AC_CHECK_FUNCS(syslog vsyslog)
# setbuffer is needed for smbtorture
AC_CHECK_FUNCS(setbuffer)
@@ -2695,7 +2695,6 @@ WINBIND_PAM_PROGS=""
if test x"$HAVE_WINBIND" = x"yes"; then
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_WINBIND)
WINBIND_TARGETS="bin/wbinfo"
WINBIND_STARGETS="bin/winbindd"
@@ -2710,6 +2709,30 @@ else
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)
@@ -2768,7 +2791,7 @@ 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)'
FLAGS1="-I$srcdir/popt"
else
@@ -2797,7 +2820,7 @@ AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
builddir=`pwd`
AC_SUBST(builddir)
-AC_OUTPUT(include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile)
+AC_OUTPUT(include/stamp-h Makefile script/findsmb)
#################################################
# Print very concise instructions on building/use
diff --git a/source3/include/ads.h b/source3/include/ads.h
index 7504a369b4..b3e18f18b8 100644
--- a/source3/include/ads.h
+++ b/source3/include/ads.h
@@ -5,34 +5,18 @@
*/
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 */
+ void *ld;
+ char *realm;
+ char *workgroup;
+ char *ldap_server;
+ char *ldap_server_name;
+ char *kdc_server;
int ldap_port;
-
- /* info needed to find the server */
- struct {
- char *realm;
- char *workgroup;
- char *ldap_server;
- 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;
- int no_bind;
- } auth;
-
- /* info derived from the servers config */
- struct {
- char *realm;
- char *bind_path;
- char *ldap_server_name;
- } config;
+ char *bind_path;
+ time_t last_attempt;
+ char *password;
+ char *user_name;
+ char *server_realm;
} ADS_STRUCT;
typedef struct {
@@ -110,7 +94,7 @@ typedef void **ADS_MODLIST;
/* macros to simplify error returning */
#define ADS_ERROR(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0)
-#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0)
+#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc, 0)
#define ADS_ERROR_KRB5(rc) ads_build_error(ADS_ERROR_KRB5, rc, 0)
#define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor)
@@ -145,25 +129,3 @@ typedef void **ADS_MODLIST;
/* account types */
#define ATYPE_GROUP 0x10000000
#define ATYPE_USER 0x30000000
-
-/* 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
diff --git a/source3/include/config.h.in b/source3/include/config.h.in
index 4a138b6db6..ac28c0856c 100644
--- a/source3/include/config.h.in
+++ b/source3/include/config.h.in
@@ -285,8 +285,6 @@
#undef _GNU_SOURCE
#endif
-#undef LDAP_SET_REBIND_PROC_ARGS
-
/* The number of bytes in a int. */
#undef SIZEOF_INT
@@ -617,9 +615,6 @@
/* Define if you have the getgrnam function. */
#undef HAVE_GETGRNAM
-/* Define if you have the getgrouplist function. */
-#undef HAVE_GETGROUPLIST
-
/* Define if you have the getnetgrent function. */
#undef HAVE_GETNETGRENT
@@ -650,9 +645,6 @@
/* Define if you have the innetgr function. */
#undef HAVE_INNETGR
-/* Define if you have the ldap_set_rebind_proc function. */
-#undef HAVE_LDAP_SET_REBIND_PROC
-
/* Define if you have the link function. */
#undef HAVE_LINK
@@ -881,6 +873,12 @@
/* Define if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
+/* Define if you have the <cups/cups.h> header file. */
+#undef HAVE_CUPS_CUPS_H
+
+/* Define if you have the <cups/language.h> header file. */
+#undef HAVE_CUPS_LANGUAGE_H
+
/* Define if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
@@ -1127,6 +1125,9 @@
/* Define if you have the acl library (-lacl). */
#undef HAVE_LIBACL
+/* Define if you have the cups library (-lcups). */
+#undef HAVE_LIBCUPS
+
/* Define if you have the gen library (-lgen). */
#undef HAVE_LIBGEN
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 6084d583ed..435810a1ba 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -707,11 +707,9 @@ extern int errno;
#include "hash.h"
#include "trans2.h"
#include "nterr.h"
-#include "ntioctl.h"
#include "messages.h"
#include "charset.h"
#include "dynconfig.h"
-#include "adt_tree.h"
#include "util_getent.h"
diff --git a/source3/include/local.h b/source3/include/local.h
index 2538715c41..24f3fa7724 100644
--- a/source3/include/local.h
+++ b/source3/include/local.h
@@ -187,20 +187,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 */
diff --git a/source3/include/messages.h b/source3/include/messages.h
index 58e606b40f..79a08a7546 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -51,7 +51,6 @@
/* #define MSG_PRINTER_NOTIFY 2001*/ /* Obsolete */
#define MSG_PRINTER_DRVUPGRADE 2002
#define MSG_PRINTER_NOTIFY2 2003
-#define MSG_PRINTERDATA_INIT_RESET 2004
/* smbd messages */
#define MSG_SMB_CONF_UPDATED 3001
diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h
index 14561cf44d..fefa243c3f 100644
--- a/source3/include/nameserv.h
+++ b/source3/include/nameserv.h
@@ -557,8 +557,6 @@ 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. */
diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index 5e2b8f7f64..57181c6659 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -174,27 +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"
-
-/* 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;
typedef struct ntdevicemode
{
@@ -259,8 +246,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;
diff --git a/source3/include/passdb.h b/source3/include/passdb.h
index 7a791ddac4..a79c8a0289 100644
--- a/source3/include/passdb.h
+++ b/source3/include/passdb.h
@@ -57,7 +57,7 @@ typedef struct pdb_context
BOOL (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
- BOOL (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid);
+ BOOL (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, DOM_SID *sid);
BOOL (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
@@ -88,7 +88,7 @@ typedef struct pdb_methods
BOOL (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username);
- BOOL (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *Sid);
+ BOOL (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, DOM_SID *Sid);
BOOL (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
diff --git a/source3/include/rpc_client_proto.h b/source3/include/rpc_client_proto.h
deleted file mode 100644
index 0ecb195691..0000000000
--- a/source3/include/rpc_client_proto.h
+++ /dev/null
@@ -1,231 +0,0 @@
-#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_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/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h
index 39f3e47dc8..8e42ac7d2c 100644
--- a/source3/include/rpc_lsa.h
+++ b/source3/include/rpc_lsa.h
@@ -73,7 +73,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
@@ -262,43 +261,6 @@ 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;
-
- GUID 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
{
diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h
index 92175cf287..3f3db0f2ba 100644
--- a/source3/include/rpc_reg.h
+++ b/source3/include/rpc_reg.h
@@ -1,10 +1,9 @@
/*
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) 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
@@ -27,35 +26,35 @@
/* winreg pipe defines
NOT IMPLEMENTED !!
+#define REG_OPEN_HKCR 0x00
#define _REG_UNK_01 0x01
#define _REG_UNK_03 0x03
#define REG_CREATE_KEY 0x06
#define REG_DELETE_KEY 0x07
#define REG_DELETE_VALUE 0x08
+#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_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
@@ -64,12 +63,6 @@
#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
@@ -89,65 +82,6 @@
#define REG_FORCE_SHUTDOWN 0x001
#define REG_REBOOT_ON_SHUTDOWN 0x100
-/* 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 {
- 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;
-
-
/* REG_Q_OPEN_HKCR */
typedef struct q_reg_open_hkcr_info
{
@@ -173,7 +107,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;
@@ -312,7 +246,6 @@ typedef struct q_reg_query_value_info
uint32 ptr2; /* pointer */
uint32 len_value2; /* */
-
} REG_Q_ENUM_VALUE;
/* REG_R_ENUM_VALUE */
@@ -325,7 +258,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; /* */
@@ -455,29 +388,6 @@ typedef struct r_reg_unk_1a_info
} 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_Q_CLOSE */
typedef struct reg_q_close_info
{
@@ -571,7 +481,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;
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index 11438ae067..78d5c244a6 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -4,10 +4,7 @@
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) Anthony Liguori 2002
- Copyright (C) Jim McDonough 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
@@ -27,8 +24,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:
@@ -145,7 +144,6 @@ SamrTestPrivateFunctionsUser
#define SAMR_GET_DOM_PWINFO 0x38
#define SAMR_CONNECT 0x39
#define SAMR_SET_USERINFO 0x3A
-#define SAMR_CONNECT4 0x3E
/* Access bits to the SAM-object */
@@ -178,17 +176,17 @@ SamrTestPrivateFunctionsUser
/* Access bits to Domain-objects */
-#define DOMAIN_ACCESS_LOOKUP_INFO_1 0x00000001
-#define DOMAIN_ACCESS_SET_INFO_1 0x00000002
-#define DOMAIN_ACCESS_LOOKUP_INFO_2 0x00000004
-#define DOMAIN_ACCESS_SET_INFO_2 0x00000008
-#define DOMAIN_ACCESS_CREATE_USER 0x00000010
-#define DOMAIN_ACCESS_CREATE_GROUP 0x00000020
-#define DOMAIN_ACCESS_CREATE_ALIAS 0x00000040
-#define DOMAIN_ACCESS_UNKNOWN_80 0x00000080
-#define DOMAIN_ACCESS_ENUM_ACCOUNTS 0x00000100
-#define DOMAIN_ACCESS_OPEN_ACCOUNT 0x00000200
-#define DOMAIN_ACCESS_SET_INFO_3 0x00000400
+#define DOMAIN_ACCESS_LOOKUP_INFO_1 0x000000001
+#define DOMAIN_ACCESS_SET_INFO_1 0x000000002
+#define DOMAIN_ACCESS_LOOKUP_INFO_2 0x000000004
+#define DOMAIN_ACCESS_SET_INFO_2 0x000000008
+#define DOMAIN_ACCESS_CREATE_USER 0x000000010
+#define DOMAIN_ACCESS_CREATE_GROUP 0x000000020
+#define DOMAIN_ACCESS_CREATE_ALIAS 0x000000040
+#define DOMAIN_ACCESS_UNKNOWN_80 0x000000080
+#define DOMAIN_ACCESS_ENUM_ACCOUNTS 0x000000100
+#define DOMAIN_ACCESS_OPEN_ACCOUNT 0x000000200
+#define DOMAIN_ACCESS_SET_INFO_3 0x000000400
#define DOMAIN_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
DOMAIN_ACCESS_SET_INFO_3 | \
@@ -222,17 +220,17 @@ SamrTestPrivateFunctionsUser
/* Access bits to User-objects */
-#define USER_ACCESS_GET_NAME_ETC 0x00000001
-#define USER_ACCESS_GET_LOCALE 0x00000002
-#define USER_ACCESS_SET_LOC_COM 0x00000004
-#define USER_ACCESS_GET_LOGONINFO 0x00000008
-#define USER_ACCESS_UNKNOWN_10 0x00000010
-#define USER_ACCESS_SET_ATTRIBUTES 0x00000020
-#define USER_ACCESS_CHANGE_PASSWORD 0x00000040
-#define USER_ACCESS_SET_PASSWORD 0x00000080
-#define USER_ACCESS_GET_GROUPS 0x00000100
-#define USER_ACCESS_UNKNOWN_200 0x00000200
-#define USER_ACCESS_UNKNOWN_400 0x00000400
+#define USER_ACCESS_GET_NAME_ETC 0x000000001
+#define USER_ACCESS_GET_LOCALE 0x000000002
+#define USER_ACCESS_SET_LOC_COM 0x000000004
+#define USER_ACCESS_GET_LOGONINFO 0x000000008
+#define USER_ACCESS_UNKNOWN_10 0x000000010
+#define USER_ACCESS_SET_ATTRIBUTES 0x000000020
+#define USER_ACCESS_CHANGE_PASSWORD 0x000000040
+#define USER_ACCESS_SET_PASSWORD 0x000000080
+#define USER_ACCESS_GET_GROUPS 0x000000100
+#define USER_ACCESS_UNKNOWN_200 0x000000200
+#define USER_ACCESS_UNKNOWN_400 0x000000400
#define USER_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
USER_ACCESS_UNKNOWN_400 | \
@@ -314,6 +312,9 @@ SamrTestPrivateFunctionsUser
#define ALIAS_EXECUTE ( STANDARD_RIGHTS_EXECUTE_ACCESS | \
ALIAS_ACCESS_LOOKUP_INFO )
+
+
+
typedef struct _DISP_USER_INFO {
SAM_ACCOUNT *sam;
} DISP_USER_INFO;
@@ -1646,7 +1647,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 */
@@ -1869,19 +1870,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
{
@@ -2020,4 +2008,6 @@ typedef struct r_samr_set_domain_info
} SAMR_R_SET_DOMAIN_INFO;
+
#endif /* _RPC_SAMR_H */
+
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h
index b7acf44c5d..7ec9a509bf 100755
--- a/source3/include/rpc_spoolss.h
+++ b/source3/include/rpc_spoolss.h
@@ -202,7 +202,6 @@
#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 PRINTER_NOTIFY_TYPE 0x00
#define JOB_NOTIFY_TYPE 0x01
@@ -802,16 +801,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;
diff --git a/source3/include/rpc_srvsvc.h b/source3/include/rpc_srvsvc.h
index 94d23bb4bc..1753c19783 100644
--- a/source3/include/rpc_srvsvc.h
+++ b/source3/include/rpc_srvsvc.h
@@ -4,7 +4,6 @@
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
@@ -34,7 +33,6 @@
#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
@@ -56,7 +54,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 {
@@ -296,29 +294,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 +306,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 +336,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 +383,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 +398,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,57 +411,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;
-
+/* SRV_SHARE_INFO_1005 */
typedef struct share_info_1005_info
{
uint32 dfs_root_flag;
} 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
{
@@ -512,16 +435,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;
@@ -567,21 +484,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;
@@ -605,16 +520,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 */
@@ -638,9 +549,7 @@ typedef struct 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 */
@@ -685,12 +594,9 @@ typedef struct str_file_info3_info
/* SRV_FILE_INFO_3 */
typedef struct srv_file_info_3
{
- uint32 num_entries_read; /* EntriesRead */
- 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 */
+
} SRV_FILE_INFO_3;
/* SRV_FILE_INFO_CTR */
diff --git a/source3/include/secrets.h b/source3/include/secrets.h
index 183b29d7a8..8a5a573bcc 100644
--- a/source3/include/secrets.h
+++ b/source3/include/secrets.h
@@ -35,10 +35,6 @@
#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 */
diff --git a/source3/python/py_conv.h b/source3/include/sids.h
index ed06b9a852..860d96b193 100644
--- a/source3/python/py_conv.h
+++ b/source3/include/sids.h
@@ -1,7 +1,9 @@
/*
- Python wrappers for DCERPC/SMB client routines.
-
- Copyright (C) Tim Potter, 2002
+ Unix SMB/CIFS implementation.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ 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
@@ -18,23 +20,20 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _PY_CONV_H
-#define _PY_CONV_H
-
-enum pyconv_types { PY_UNISTR, PY_UINT32, PY_UINT16 };
+#ifndef _SIDS_H
+#define _SIDS_H
-struct pyconv {
- char *name; /* Name of member */
- enum pyconv_types type; /* Type */
- size_t offset; /* Offset into structure */
-};
+extern DOM_SID global_sam_sid;
+extern fstring global_sam_name;
-PyObject *from_struct(void *s, struct pyconv *conv);
-BOOL to_struct(void *s, PyObject *dict, struct pyconv *conv);
+extern DOM_SID global_member_sid;
-/* Another version of offsetof (-: */
+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;
-#undef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+extern const DOM_SID *global_sid_everyone;
+extern const DOM_SID *global_sid_system; /* SYSTEM */
+extern const DOM_SID *global_sid_builtin;
-#endif /* _PY_CONV_H */
+#endif /* _SIDS_H */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 263dd67c54..a67101ff09 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -38,9 +38,7 @@
#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 False (0)
#define True (1)
@@ -385,7 +383,7 @@ typedef struct files_struct
int fnum;
struct connection_struct *conn;
int fd;
- uint32 print_jobid;
+ int print_jobid;
SMB_DEV_T dev;
SMB_INO_T inode;
BOOL delete_on_close;
@@ -446,15 +444,6 @@ typedef struct
#include "smb_acls.h"
#include "vfs.h"
-typedef struct smb_vfs_handle_struct
-{
- void *data;
- /* Handle on dlopen() call */
- void *handle;
- struct smb_vfs_handle_struct *next, *prev;
-
-} smb_vfs_handle_struct;
-
typedef struct connection_struct
{
struct connection_struct *next, *prev;
@@ -472,7 +461,9 @@ typedef struct connection_struct
char *origpath;
struct vfs_ops vfs_ops; /* Filesystem operations */
- struct smb_vfs_handle_struct *vfs_private;
+ /* 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 */
@@ -1603,8 +1594,8 @@ typedef struct user_struct
uint8 session_key[16];
- char *session_keystr; /* used by utmp and pam session code.
- TDB key string */
+ int session_id; /* used by utmp and pam session code */
+
int homes_snum;
} user_struct;
@@ -1676,8 +1667,4 @@ typedef struct {
#define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14
-/* Common popt structures */
-
-extern struct poptOption popt_common_debug[];
-
#endif /* _SMB_H */
diff --git a/source3/include/version.h b/source3/include/version.h
index 74df1c9914..afc40a8cf9 100644
--- a/source3/include/version.h
+++ b/source3/include/version.h
@@ -1 +1 @@
-#define VERSION "3.0-alpha18"
+#define VERSION "3.0-alpha17"
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 1b1a13d7c1..2f9fedf77d 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -1,8 +1,7 @@
/*
Unix SMB/CIFS implementation.
VFS structures and parameters
- Copyright (C) Tim Potter 1999
- Copyright (C) Alexander Bokovoy 2002
+ 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
@@ -17,8 +16,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
@@ -43,48 +40,7 @@
/* 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. */
-#define SMB_VFS_INTERFACE_VERSION 5
-
-
-/* Version of supported cascaded interface backward copmatibility.
- (version 4 corresponds to SMB_VFS_INTERFACE_VERSION 4)
- It is used in vfs_init_custom() to detect VFS modules which conform to cascaded
- VFS interface but implement elder version than current version of Samba uses.
- This allows to use old modules with new VFS interface as far as combined VFS operation
- set is coherent (will be in most cases).
-*/
-#define SMB_VFS_INTERFACE_CASCADED 4
-
-/*
- Each VFS module must provide following global functions:
- vfs_init -- initialization function
- vfs_done -- finalization function
-
- vfs_init must return proper initialized vfs_op_tuple[] array
- which describes all operations this module claims to intercept. This function
- is called whenever module is loaded into smbd process using sys_dlopen().
-
- vfs_init must store somewhere vfs_handle reference if module wants to store per-instance
- private information for further usage. vfs_handle->data should be used to
- store such information. Do not try to change other fields in this structure
- or results likely to be unpredictable.
-
- vfs_done must perform finalization of the module. In particular,
- this function must free vfs_ops structure returned to module from smb_vfs_get_opaque_ops()
- function if it is used (see below). This function is called whenever module
- is unloaded from smbd process using sys_dlclose().
-
- Prototypes:
- vfs_op_tuple *vfs_init(int *vfs_version, const struct vfs_ops *def_vfs_ops,
- struct smb_vfs_handle_struct *vfs_handle);
- void vfs_done(connection_struct *conn);
-
- All intercepted VFS operations must be declared as static functions inside module source
- in order to keep smbd namespace unpolluted. See source of skel, audit, and recycle bin
- example VFS modules for more details.
-
-*/
+#define SMB_VFS_INTERFACE_VERSION 3
/* VFS operations structure */
@@ -179,157 +135,4 @@ struct vfs_options {
char *value;
};
-/*
- Available VFS operations. These values must be in sync with vfs_ops struct.
- 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.
-*/
-
-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,
-
- /* Directory operations */
-
- SMB_VFS_OP_OPENDIR,
- SMB_VFS_OP_READDIR,
- SMB_VFS_OP_MKDIR,
- SMB_VFS_OP_RMDIR,
- SMB_VFS_OP_CLOSEDIR,
-
- /* File operations */
-
- SMB_VFS_OP_OPEN,
- SMB_VFS_OP_CLOSE,
- SMB_VFS_OP_READ,
- SMB_VFS_OP_WRITE,
- SMB_VFS_OP_LSEEK,
- 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,
-
- /* 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,
-
- /* 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,
-
- /* This should always be last enum value */
-
- SMB_VFS_OP_LAST
-} vfs_op_type;
-
-/*
- 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 does 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 initialization function returns to VFS subsystem
- an array of vfs_op_tuple which describes all operations this module is willing to intercept.
- VFS subsystem initializes then vfs_ops using this information and passes it
- to next VFS module as underlying vfs_ops and to connection after all VFS modules are initialized.
-*/
-
-typedef struct _vfs_op_tuple {
- void* op;
- vfs_op_type type;
- vfs_op_layer layer;
-} vfs_op_tuple;
-
-/*
- Return vfs_ops filled with current opaque VFS operations. This function is designed to
- be called from VFS module initialization function for those modules which needs 'direct' VFS
- access (loggers or initiators of file operations other than connection asks for).
-
- Returned vfs_ops must be cleaned up in VFS module's finalizer function (vfs_done_<module_name>)
- using safe_free().
-
- Prototype:
- struct vfs_ops *smb_vfs_get_opaque_ops();
-
- This prototype will be available via include/proto.h
-*/
-
#endif /* _VFS_H */
diff --git a/source3/intl/lang_tdb.c b/source3/intl/lang_tdb.c
index a86ea0a3f9..d5e8bd41bd 100644
--- a/source3/intl/lang_tdb.c
+++ b/source3/intl/lang_tdb.c
@@ -106,10 +106,8 @@ BOOL lang_tdb_init(const char *lang)
if (initialised) {
/* we are re-initialising, free up any old init */
- if (tdb) {
- tdb_close(tdb);
- tdb = NULL;
- }
+ tdb_close(tdb);
+ tdb = NULL;
SAFE_FREE(current_lang);
}
diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c
index 07b5e2ecfc..07676e2202 100644
--- a/source3/lib/account_pol.c
+++ b/source3/lib/account_pol.c
@@ -2,7 +2,6 @@
* 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
@@ -32,7 +31,6 @@ BOOL init_account_policy(void)
{
static pid_t local_pid;
char *vstring = "INFO/version";
- uint32 version;
if (tdb && local_pid == sys_getpid())
return True;
@@ -46,9 +44,9 @@ BOOL init_account_policy(void)
/* handle a Samba upgrade */
tdb_lock_bystring(tdb, vstring);
- if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
+ if (tdb_fetch_int32(tdb, vstring) != DATABASE_VERSION) {
tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
- tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
+ tdb_store_int32(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 */
@@ -65,50 +63,33 @@ BOOL init_account_policy(void)
return True;
}
-static const struct {
- int field;
- 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)
+static char *decode_account_policy_name(int field)
{
- 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;
+ switch (field) {
+ case AP_MIN_PASSWORD_LEN:
+ return "min password length";
+ case AP_PASSWORD_HISTORY:
+ return "password history";
+ case AP_USER_MUST_LOGON_TO_CHG_PASS:
+ return "user must logon to change password";
+ case AP_MAX_PASSWORD_AGE:
+ return "maximum password age";
+ case AP_MIN_PASSWORD_AGE:
+ return "minimum password age";
+ case AP_LOCK_ACCOUNT_DURATION:
+ return "lockout duration";
+ case AP_RESET_COUNT_TIME:
+ return "reset count minutes";
+ case AP_BAD_ATTEMPT_LOCKOUT:
+ return "bad lockout attempt";
+ case AP_TIME_TO_LOGOUT:
+ return "disconnect time";
+ default:
+ return "undefined value";
}
- return 0;
-
}
@@ -120,17 +101,8 @@ BOOL account_policy_get(int field, uint32 *value)
init_account_policy();
- *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 feild %d (%s), returning 0", field, name));
- return False;
- }
+ *value=tdb_fetch_int32(tdb, name);
DEBUG(10,("account_policy_get: %s:%d\n", name, *value));
return True;
}
@@ -145,16 +117,8 @@ BOOL account_policy_set(int field, uint32 value)
init_account_policy();
fstrcpy(name, decode_account_policy_name(field));
- if (!*name) {
- DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", field));
+ if ( tdb_store_int32(tdb, name, value)== -1)
return False;
- }
-
- if (!tdb_store_uint32(tdb, name, value)) {
- DEBUG(1, ("tdb_store_uint32 failed for feild %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/source3/lib/charcnv.c b/source3/lib/charcnv.c
index 6e96136643..d42dc994b0 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -249,15 +249,15 @@ convert:
size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
void const *src, size_t srclen, void **dest)
{
- void *alloced_string;
+ void *ob;
size_t dest_len;
*dest = NULL;
- dest_len=convert_string_allocate(from, to, src, srclen, &alloced_string);
+ dest_len=convert_string_allocate(from, to, src, srclen, (void **)&ob);
if (dest_len == -1)
return -1;
- *dest = talloc_memdup(ctx, alloced_string, dest_len);
- SAFE_FREE(alloced_string);
+ *dest = talloc_strdup(ctx, (char *)ob);
+ SAFE_FREE(ob);
if (*dest == NULL)
return -1;
return dest_len;
@@ -505,12 +505,12 @@ int push_utf8_pstring(void *dest, const char *src)
*
* @retval The number of bytes occupied by the string in the destination
**/
-int push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
+int push_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
{
int src_len = strlen(src)+1;
*dest = NULL;
- return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest);
+ return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, dest);
}
/**
@@ -562,8 +562,7 @@ int pull_ucs2(const void *base_ptr, char *dest, const void *src, int dest_len, i
}
/* ucs2 is always a multiple of 2 bytes */
- if (src_len != -1)
- src_len &= ~1;
+ src_len &= ~1;
ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len);
if (dest_len) dest[MIN(ret, dest_len-1)] = 0;
@@ -659,11 +658,11 @@ int pull_utf8_fstring(char *dest, const void *src)
*
* @retval The number of bytes occupied by the string in the destination
**/
-int pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
+int pull_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
{
int src_len = strlen(src)+1;
*dest = NULL;
- return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);
+ return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, dest);
}
/**
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index 842d2dac1d..f41c3b6497 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -423,7 +423,7 @@ BOOL debug_parse_levels(const char *params_str)
if (AllowDebugChange == False)
return True;
- params = str_list_make(params_str, NULL);
+ params = str_list_make(params_str);
if (debug_parse_params(params, DEBUGLEVEL_CLASS,
DEBUGLEVEL_CLASS_ISSET))
@@ -602,12 +602,6 @@ BOOL reopen_logs( void )
force_check_log_size();
(void)umask(oldumask);
- /* Take over stderr to catch ouput into logs */
- if (dbf && sys_dup2(dbf->fd, 2) == -1) {
- close_low_fds(True); /* Close stderr too, if dup2 can't point it
- at the logfile */
- }
-
return ret;
}
diff --git a/source3/lib/domain_namemap.c b/source3/lib/domain_namemap.c
deleted file mode 100644
index 988f5e5d65..0000000000
--- a/source3/lib/domain_namemap.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-/*
- 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 int DEBUGLEVEL;
-
-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)
-{
- if (gmep->grp.nt_name)
- {
- free(gmep->grp.nt_name);
- }
- if (gmep->grp.nt_domain)
- {
- free(gmep->grp.nt_domain);
- }
- if (gmep->grp.unix_name)
- {
- free(gmep->grp.unix_name);
- }
- free((char*)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;
- }
- if (types != NULL)
- {
- free(types);
- }
-
- if (sids != NULL)
- {
- 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/source3/lib/genrand.c b/source3/lib/genrand.c
index fe756169a6..ee8bc0b1d5 100644
--- a/source3/lib/genrand.c
+++ b/source3/lib/genrand.c
@@ -259,7 +259,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/source3/lib/replace.c b/source3/lib/replace.c
index fd7b2cf7f0..2cc7d48adb 100644
--- a/source3/lib/replace.c
+++ b/source3/lib/replace.c
@@ -428,5 +428,3 @@ char *rep_inet_ntoa(struct in_addr ip)
}
#endif /* HAVE_SYSLOG */
#endif /* HAVE_VSYSLOG */
-
-
diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c
index 592543bc43..67f82ed0ad 100644
--- a/source3/lib/smbrun.c
+++ b/source3/lib/smbrun.c
@@ -143,7 +143,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/source3/lib/substitute.c b/source3/lib/substitute.c
index 026df0f67f..6d96a1820f 100644
--- a/source3/lib/substitute.c
+++ b/source3/lib/substitute.c
@@ -25,41 +25,9 @@ fstring local_machine="";
fstring remote_arch="UNKNOWN";
userdom_struct current_user_info;
fstring remote_proto="UNKNOWN";
+fstring remote_machine="";
extern pstring global_myname;
-static fstring remote_machine="";
-
-
-void set_local_machine_name(const char* local_name)
-{
- fstring tmp_local_machine;
-
- fstrcpy(tmp_local_machine,local_name);
- trim_string(tmp_local_machine," "," ");
- strlower(tmp_local_machine);
- alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
-}
-
-void set_remote_machine_name(const char* remote_name)
-{
- fstring tmp_remote_machine;
-
- fstrcpy(tmp_remote_machine,remote_name);
- trim_string(tmp_remote_machine," "," ");
- strlower(tmp_remote_machine);
- alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
-}
-
-const char* get_remote_machine_name(void)
-{
- return remote_machine;
-}
-
-const char* get_local_machine_name(void)
-{
- return local_machine;
-}
-
/*******************************************************************
Given a pointer to a %$(NAME) expand it as an environment variable.
Return the number of characters by which the pointer should be advanced.
@@ -220,15 +188,14 @@ 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(const char *user_name)
{
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);
@@ -262,7 +229,6 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
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) {
fstring tmp_str;
@@ -295,8 +261,8 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
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
string_sub(p,"%L", global_myname,l);
break;
@@ -320,7 +286,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
string_sub(p,"%h", myhostname(),l);
break;
case 'm' :
- string_sub(p,"%m", get_remote_machine_name(),l);
+ string_sub(p,"%m", remote_machine,l);
break;
case 'v' :
string_sub(p,"%v", VERSION,l);
@@ -415,7 +381,6 @@ 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();
a_string = strdup(str);
if (a_string == NULL) {
@@ -450,8 +415,8 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
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);
+ if (*local_machine)
+ t = realloc_string_sub(t, "%L", local_machine);
else
t = realloc_string_sub(t, "%L", global_myname);
break;
diff --git a/source3/lib/system.c b/source3/lib/system.c
index edda54a78d..8b2ba800f5 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -1219,16 +1219,6 @@ 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.
****************************************************************************/
diff --git a/source3/lib/username.c b/source3/lib/username.c
index 5db7f58b1e..4813c8fd19 100644
--- a/source3/lib/username.c
+++ b/source3/lib/username.c
@@ -163,7 +163,7 @@ BOOL map_username(char *user)
}
}
- dosuserlist = str_list_make(dosname, NULL);
+ dosuserlist = str_list_make(dosname);
if (!dosuserlist) {
DEBUG(0,("Unable to build user list\n"));
return False;
diff --git a/source3/lib/util.c b/source3/lib/util.c
index ae94b710b2..be108aa405 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -100,7 +100,7 @@ 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;
@@ -503,32 +503,27 @@ void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,ti
/*******************************************************************
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)
{
int fd;
int i;
close(0); close(1);
-
- if (stderr_too) {
- close(2);
- }
-
+#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++) {
- 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;
- }
+ 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;
+ }
}
}
@@ -683,8 +678,7 @@ void become_daemon(void)
#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();
}
diff --git a/source3/lib/util_getent.c b/source3/lib/util_getent.c
index 6699ce3e92..2e76121aae 100644
--- a/source3/lib/util_getent.c
+++ b/source3/lib/util_getent.c
@@ -21,6 +21,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.
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index ad09f91234..5dd1d75c70 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -365,9 +365,6 @@ BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid)
{
int i;
if (len < 8) return False;
-
- ZERO_STRUCTP(sid);
-
sid->sid_rev_num = CVAL(inbuf, 0);
sid->num_auths = CVAL(inbuf, 1);
memcpy(sid->id_auth, inbuf+2, 6);
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index 5e2b7c5ed9..4f1f2a1470 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -708,7 +708,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) );
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 19d92eec8f..88a72f1536 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -212,18 +212,6 @@ int strwicmp(const char *psz1, const char *psz2)
}
-/* Convert a string to upper case, but don't modify it */
-
-char *strupper_static(const char *s)
-{
- static pstring str;
-
- pstrcpy(str, s);
- strupper(str);
-
- return str;
-}
-
/*******************************************************************
convert a string to "normal" form
********************************************************************/
@@ -311,7 +299,7 @@ BOOL trim_string(char *s,const char *front,const char *back)
}
if (back_len) {
- while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
+ while (strncmp(s+len-back_len,back,back_len)==0) {
s[len-back_len]='\0';
len -= back_len;
ret=True;
@@ -679,7 +667,7 @@ void string_sub(char *s,const char *pattern, const char *insert, size_t len)
li = (ssize_t)strlen(insert);
if (len == 0)
- len = ls + 1; /* len is number of *bytes* */
+ len = ls;
while (lp <= ls && (p = strstr(s,pattern))) {
if (ls + (li-lp) >= len) {
@@ -810,7 +798,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
return;
if (len == 0)
- len = ls + 1; /* len is number of *bytes* */
+ len = ls;
while (lp <= ls && (p = strstr(s,pattern))) {
if (ls + (li-lp) >= len) {
@@ -838,8 +826,7 @@ return a new allocate unicode string.
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;
+ smb_ucs2_t *r, *rp, *sp;
size_t lr, lp, li, lt;
if (!insert || !pattern || !*pattern || !s) return NULL;
@@ -849,7 +836,7 @@ smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
li = (size_t)strlen_w(insert);
if (li > lp) {
- const smb_ucs2_t *st = s;
+ smb_ucs2_t *st = s;
int ld = li - lp;
while ((sp = strstr_w(st, pattern))) {
st = sp + lp;
@@ -892,59 +879,68 @@ smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
}
/****************************************************************************
- Splits out the front and back at a separator.
+ splits out the front and back at a separator.
****************************************************************************/
-
void split_at_last_component(char *path, char *front, char sep, char *back)
{
char *p = strrchr_m(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;
+ }
}
}
+
/****************************************************************************
- Write an octal as a string.
+write an octal as a string
****************************************************************************/
-
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.
+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.
+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 *s, char c)
{
wpstring ws;
@@ -953,8 +949,7 @@ char *strchr_m(const char *s, char c)
push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
p = strchr_w(ws, UCS2_CHAR(c));
- if (!p)
- return NULL;
+ if (!p) return NULL;
*p = 0;
pull_ucs2_pstring(s2, ws);
return (char *)(s+strlen(s2));
@@ -968,29 +963,26 @@ char *strrchr_m(const char *s, char c)
push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
p = strrchr_w(ws, UCS2_CHAR(c));
- if (!p)
- return NULL;
+ if (!p) return NULL;
*p = 0;
pull_ucs2_pstring(s2, ws);
return (char *)(s+strlen(s2));
}
/*******************************************************************
- Convert a string to lower case.
+ convert a string to lower case
********************************************************************/
-
void strlower_m(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) */
-
- while (*s && !(((unsigned char)s[0]) & 0x7F))
+ while (*s && !(((unsigned char)s[0]) & 0x7F)) {
*s++ = tolower((unsigned char)*s);
+ }
- if (!*s)
- return;
+ if (!*s) return;
/* I assume that lowercased string takes the same number of bytes
* as source string even in UTF-8 encoding. (VIV) */
@@ -998,9 +990,8 @@ void strlower_m(char *s)
}
/*******************************************************************
- Duplicate convert a string to lower case.
+ duplicate convert a string to lower case
********************************************************************/
-
char *strdup_lower(const char *s)
{
char *t = strdup(s);
@@ -1013,21 +1004,19 @@ char *strdup_lower(const char *s)
}
/*******************************************************************
- Convert a string to upper case.
+ convert a string to upper case
********************************************************************/
-
void strupper_m(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) */
-
- while (*s && !(((unsigned char)s[0]) & 0x7F))
+ while (*s && !(((unsigned char)s[0]) & 0x7F)) {
*s++ = toupper((unsigned char)*s);
+ }
- if (!*s)
- return;
+ if (!*s) return;
/* I assume that lowercased string takes the same number of bytes
* as source string even in multibyte encoding. (VIV) */
@@ -1035,9 +1024,8 @@ void strupper_m(char *s)
}
/*******************************************************************
- Convert a string to upper case.
+ convert a string to upper case
********************************************************************/
-
char *strdup_upper(const char *s)
{
char *t = strdup(s);
@@ -1060,8 +1048,7 @@ char *binary_string(char *buf, int len)
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];
@@ -1072,8 +1059,8 @@ char *binary_string(char *buf, int len)
return s;
}
-/* Just a typesafety wrapper for snprintf into a pstring */
+/* Just a typesafety wrapper for snprintf into a pstring */
int pstr_sprintf(pstring s, const char *fmt, ...)
{
va_list ap;
@@ -1085,8 +1072,8 @@ int pstr_sprintf(pstring s, const char *fmt, ...)
return ret;
}
-/* Just a typesafety wrapper for snprintf into a fstring */
+/* Just a typesafety wrapper for snprintf into a fstring */
int fstr_sprintf(fstring s, const char *fmt, ...)
{
va_list ap;
@@ -1098,19 +1085,18 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
return ret;
}
+
#ifndef HAVE_STRNDUP
/*******************************************************************
- Some platforms don't 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)
- return NULL;
+ if (!ret) return NULL;
memcpy(ret, s, n);
ret[n] = 0;
@@ -1125,39 +1111,39 @@ 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 */ ;
+ 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 **str_list_make(const char *string)
{
char **list, **rlist;
char *str, *s;
int num, lsize;
pstring tok;
- if (!string || !*string)
- return NULL;
+ 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))) {
+ while (next_token(&str, tok, LIST_SEP, sizeof(tok)))
+ {
if (num == lsize) {
lsize += S_LIST_ABS;
rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
@@ -1192,13 +1178,13 @@ BOOL str_list_copy(char ***dest, char **src)
int num, lsize;
*dest = NULL;
- if (!src)
- return False;
+ if (!src) return False;
num = lsize = 0;
list = NULL;
- while (src[num]) {
+ while (src[num])
+ {
if (num == lsize) {
lsize += S_LIST_ABS;
rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
@@ -1226,22 +1212,17 @@ BOOL str_list_copy(char ***dest, char **src)
}
/* return true if all the elemnts of the list matches exactly */
-
BOOL str_list_compare(char **list1, char **list2)
{
int num;
- if (!list1 || !list2)
- return (list1 == list2);
+ 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 (!strcsequal(list1[num], list2[num])) return False;
}
- if (list2[num])
- return False; /* if list2 has more elements than list1 fail */
+ if (list2[num]) return False; /* if list2 has more elements than list1 fail */
return True;
}
@@ -1250,11 +1231,9 @@ void str_list_free(char ***list)
{
char **tlist;
- if (!list || !*list)
- return;
+ if (!list || !*list) return;
tlist = *list;
- for(; *tlist; tlist++)
- SAFE_FREE(*tlist);
+ for(; *tlist; tlist++) SAFE_FREE(*tlist);
SAFE_FREE(*list);
}
@@ -1263,25 +1242,25 @@ 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;
+ 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) {
+ while (*list)
+ {
s = *list;
ls = (ssize_t)strlen(s);
- while ((p = strstr(s, pattern))) {
+ while ((p = strstr(s, pattern)))
+ {
t = *list;
d = p -t;
- if (ld) {
+ if (ld)
+ {
t = (char *) malloc(ls +ld +1);
if (!t) {
DEBUG(0,("str_list_substitute: Unable to allocate memory"));
diff --git a/source3/lib/wins_srv.c b/source3/lib/wins_srv.c
index 61e77aca58..adf405ae7e 100644
--- a/source3/lib/wins_srv.c
+++ b/source3/lib/wins_srv.c
@@ -236,7 +236,7 @@ char **wins_srv_tags(void)
}
/* add it to the list */
- ret = (char **)Realloc(ret, (count+2) * sizeof(char *));
+ ret = (char **)Realloc(ret, (count+1) * sizeof(char *));
ret[count] = strdup(t_ip.tag);
if (!ret[count]) break;
count++;
diff --git a/source3/lib/xfile.c b/source3/lib/xfile.c
index b5710f3a39..903dfb1ae0 100644
--- a/source3/lib/xfile.c
+++ b/source3/lib/xfile.c
@@ -171,7 +171,7 @@ int x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f)
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--) {
+ for (i=size-1; i>=0; i--) {
if (*(i+(const char *)p) == '\n') {
x_fflush(f);
break;
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c
index b68c822ce3..638dc0b22e 100644
--- a/source3/libads/ads_struct.c
+++ b/source3/libads/ads_struct.c
@@ -72,6 +72,47 @@ char *ads_build_dn(const char *realm)
}
+#ifdef HAVE_LDAP
+/*
+ find the ldap server from DNS
+*/
+static char *find_ldap_server(ADS_STRUCT *ads)
+{
+ char *list = NULL;
+ struct in_addr ip;
+
+ if (ads->realm &&
+ strcasecmp(ads->workgroup, lp_workgroup()) == 0 &&
+ ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) {
+ char *p;
+ p = strchr(list, ':');
+ if (p) *p = 0;
+ return list;
+ }
+
+ /* get desperate, find the domain controller IP */
+ if (resolve_name(ads->workgroup, &ip, 0x1B)) {
+ return strdup(inet_ntoa(ip));
+ }
+
+ /* or a BDC ... */
+ if (resolve_name(ads->workgroup, &ip, 0x1C)) {
+ return strdup(inet_ntoa(ip));
+ }
+
+ return NULL;
+}
+
+#else
+
+static char *find_ldap_server(ADS_STRUCT *ads)
+{
+ /* Without LDAP this doesn't make much sense */
+ return NULL;
+}
+
+#endif
+
#ifndef LDAP_PORT
#define LDAP_PORT 389
#endif
@@ -81,24 +122,46 @@ char *ads_build_dn(const char *realm)
*/
ADS_STRUCT *ads_init(const char *realm,
const char *workgroup,
- const char *ldap_server)
+ const char *ldap_server,
+ const char *bind_path,
+ const char *password)
{
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 to know if we can
- use lp_ads_server() */
- if (realm && strcasecmp(lp_realm(), realm) != 0) {
- ads->server.foreign = 1;
+ if (!workgroup) {
+ workgroup = lp_workgroup();
}
- if (workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) {
- ads->server.foreign = 1;
+
+ ads->realm = realm? strdup(realm) : NULL;
+ ads->workgroup = strdup(workgroup);
+ ads->ldap_server = ldap_server? strdup(ldap_server) : NULL;
+ ads->bind_path = bind_path? strdup(bind_path) : NULL;
+ ads->ldap_port = LDAP_PORT;
+ if (password) ads->password = strdup(password);
+
+ if (!ads->realm) {
+ ads->realm = strdup(lp_realm());
+ if (!ads->realm[0]) {
+ SAFE_FREE(ads->realm);
+ }
+ }
+ if (!ads->bind_path && ads->realm) {
+ ads->bind_path = ads_build_dn(ads->realm);
+ }
+ if (!ads->ldap_server) {
+ if (strcasecmp(ads->workgroup, lp_workgroup()) == 0) {
+ ads->ldap_server = strdup(lp_ads_server());
+ }
+ if (!ads->ldap_server || !ads->ldap_server[0]) {
+ ads->ldap_server = find_ldap_server(ads);
+ }
+ }
+ if (!ads->kdc_server) {
+ /* assume its the same as LDAP */
+ ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL;
}
return ads;
@@ -107,7 +170,7 @@ ADS_STRUCT *ads_init(const char *realm,
/* a simpler ads_init() interface using all defaults */
ADS_STRUCT *ads_init_simple(void)
{
- return ads_init(NULL, NULL, NULL);
+ return ads_init(NULL, NULL, NULL, NULL, NULL);
}
/*
@@ -119,19 +182,13 @@ void ads_destroy(ADS_STRUCT **ads)
#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)->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);
-
+ SAFE_FREE((*ads)->realm);
+ SAFE_FREE((*ads)->ldap_server);
+ SAFE_FREE((*ads)->ldap_server_name);
+ SAFE_FREE((*ads)->kdc_server);
+ SAFE_FREE((*ads)->bind_path);
+ SAFE_FREE((*ads)->password);
+ SAFE_FREE((*ads)->user_name);
ZERO_STRUCTP(*ads);
SAFE_FREE(*ads);
}
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index 9a486237c9..1ba5d978e8 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -110,8 +110,16 @@ int ads_kinit_password(ADS_STRUCT *ads)
char *s;
int ret;
- asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm);
- ret = kerberos_kinit_password(s, ads->auth.password);
+ if (!ads->user_name) {
+ /* by default use the machine account */
+ extern pstring global_myname;
+ fstring myname;
+ fstrcpy(myname, global_myname);
+ strlower(myname);
+ asprintf(&ads->user_name, "HOST/%s", global_myname);
+ }
+ asprintf(&s, "%s@%s", ads->user_name, ads->realm);
+ ret = kerberos_kinit_password(s, ads->password);
if (ret) {
DEBUG(0,("kerberos_kinit_password %s failed: %s\n",
diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c
index 22b58f47dd..dac90908c4 100644
--- a/source3/libads/kerberos_verify.c
+++ b/source3/libads/kerberos_verify.c
@@ -67,7 +67,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
return NT_STATUS_LOGON_FAILURE;
}
- ret = krb5_set_default_realm(context, ads->auth.realm);
+ ret = krb5_set_default_realm(context, ads->realm);
if (ret) {
DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
ads_destroy(&ads);
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 2672489482..9d15c4e33c 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -37,165 +37,6 @@
* 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
- */
-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;
-}
-
-/* used by the IP comparison function */
-struct ldap_ip {
- struct in_addr ip;
- unsigned port;
-};
-
-/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */
-static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2)
-{
- return ip_compare(&ip1->ip, &ip2->ip);
-}
-
-/* try connecting to a ldap server via DNS */
-static BOOL ads_try_dns(ADS_STRUCT *ads)
-{
- char *realm, *ptr;
- char *list = NULL;
- pstring tok;
- struct ldap_ip *ip_list;
- int count, i=0;
-
- realm = ads->server.realm;
- if (!realm || !*realm) {
- realm = lp_realm();
- }
- if (!realm || !*realm) {
- realm = ads->server.workgroup;
- }
- if (!realm || !*realm) {
- realm = lp_workgroup();
- }
- if (!realm) {
- return False;
- }
- realm = smb_xstrdup(realm);
-
- DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm));
- if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) {
- SAFE_FREE(realm);
- return False;
- }
-
- DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list));
- SAFE_FREE(realm);
-
- count = count_chars(list, ' ') + 1;
- ip_list = malloc(count * sizeof(struct ldap_ip));
- if (!ip_list) {
- 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);
- }
- ip_list[i].ip = *interpret_addr2(tok);
- ip_list[i].port = port;
- if (!is_zero_ip(ip_list[i].ip)) {
- i++;
- }
- }
- free(list);
-
- count = i;
-
- /* we sort the list of addresses by closeness to our interfaces. This
- tries to prevent us using a DC on the other side of the country */
- if (count > 1) {
- qsort(ip_list, count, sizeof(struct ldap_ip),
- QSORT_CAST ldap_ip_compare);
- }
-
- for (i=0;i<count;i++) {
- if (ads_try_connect(ads, inet_ntoa(ip_list[i].ip), ip_list[i].port)) {
- free(ip_list);
- return True;
- }
- }
-
- SAFE_FREE(ip_list);
- return False;
-}
-
-/* try connecting to a ldap server via netbios */
-static BOOL ads_try_netbios(ADS_STRUCT *ads)
-{
- struct in_addr *ip_list;
- int count;
- int i;
- char *workgroup = ads->server.workgroup;
-
- if (!workgroup) {
- workgroup = lp_workgroup();
- }
-
- DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup));
-
- /* try the PDC first */
- if (get_dc_list(True, workgroup, &ip_list, &count)) {
- for (i=0;i<count;i++) {
- DEBUG(6,("ads_try_netbios: trying server '%s'\n",
- inet_ntoa(ip_list[i])));
- if (ads_try_connect(ads, inet_ntoa(ip_list[i]), LDAP_PORT)) {
- free(ip_list);
- return True;
- }
- }
- free(ip_list);
- }
-
- /* now any DC, including backups */
- if (get_dc_list(False, workgroup, &ip_list, &count)) {
- for (i=0;i<count;i++) {
- DEBUG(6,("ads_try_netbios: trying server '%s'\n",
- inet_ntoa(ip_list[i])));
- if (ads_try_connect(ads, inet_ntoa(ip_list[i]), LDAP_PORT)) {
- free(ip_list);
- return True;
- }
- }
- free(ip_list);
- }
-
- return False;
-}
-
/**
* Connect to the LDAP server
* @param ads Pointer to an existing ADS_STRUCT
@@ -208,35 +49,38 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
ADS_STATUS status;
ads->last_attempt = time(NULL);
- ads->ld = NULL;
- /* try with a user specified server */
- if (ads->server.ldap_server &&
- ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) {
- goto got_connection;
- }
+ ads->ld = NULL;
- /* try with a smb.conf ads server setting if we are connecting
- to the primary workgroup or realm */
- if (!ads->server.foreign &&
- ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) {
- goto got_connection;
+ if (ads->ldap_server) {
+ ads->ld = ldap_open(ads->ldap_server, ads->ldap_port);
}
- /* try via DNS */
- if (ads_try_dns(ads)) {
- goto got_connection;
+ /* if that failed then try each of the BDC's in turn */
+ if (!ads->ld) {
+ struct in_addr *ip_list;
+ int count;
+
+ if (get_dc_list(False, ads->workgroup, &ip_list, &count)) {
+ int i;
+ for (i=0;i<count;i++) {
+ ads->ld = ldap_open(inet_ntoa(ip_list[i]),
+ ads->ldap_port);
+ if (ads->ld) break;
+ }
+ if (ads->ld) {
+ SAFE_FREE(ads->ldap_server);
+ ads->ldap_server = strdup(inet_ntoa(ip_list[i]));
+ }
+ free(ip_list);
}
-
- /* try via netbios lookups */
- if (!lp_disable_netbios() && ads_try_netbios(ads)) {
- goto got_connection;
}
- return ADS_ERROR_SYSTEM(errno?errno:ENOENT);
+ if (!ads->ld) {
+ return ADS_ERROR_SYSTEM(errno);
+ }
-got_connection:
- DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip)));
+ DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server));
status = ads_server_info(ads);
if (!ADS_ERR_OK(status)) {
@@ -246,43 +90,22 @@ got_connection:
ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
- if (!ads->auth.user_name) {
- /* by default use the machine account */
- extern pstring global_myname;
- fstring myname;
- fstrcpy(myname, global_myname);
- strlower(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);
+ asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->server_realm);
+ setenv(env, inet_ntoa(*interpret_addr2(ads->ldap_server)), 1);
free(env);
}
#endif
- if (ads->auth.password) {
+ if (ads->password) {
if ((code = ads_kinit_password(ads)))
return ADS_ERROR_KRB5(code);
}
- if (ads->auth.no_bind) {
- return ADS_SUCCESS;
- }
-
return ads_sasl_bind(ads);
}
@@ -338,7 +161,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals)
if (!values) return NULL;
for (i=0; in_vals[i]; i++) {
- push_utf8_talloc(ctx, &values[i], in_vals[i]);
+ push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]);
}
return values;
}
@@ -357,7 +180,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals)
if (!values) return NULL;
for (i=0; in_vals[i]; i++) {
- pull_utf8_talloc(ctx, &values[i], in_vals[i]);
+ pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]);
}
return values;
}
@@ -396,8 +219,8 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
/* 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_exp, exp) < 0) ||
- (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) {
+ if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) ||
+ (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) {
rc = LDAP_NO_MEMORY;
goto done;
}
@@ -407,7 +230,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
else {
/* This would be the utf8-encoded version...*/
/* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
- if (!(str_list_copy(&search_attrs, attrs)))
+ if (!(str_list_copy(&search_attrs, (char **) attrs)))
{
rc = LDAP_NO_MEMORY;
goto done;
@@ -619,8 +442,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
/* 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_exp, exp) < 0) ||
- (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) {
+ if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) ||
+ (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) {
rc = LDAP_NO_MEMORY;
goto done;
}
@@ -630,7 +453,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
else {
/* This would be the utf8-encoded version...*/
/* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
- if (!(str_list_copy(&search_attrs, attrs)))
+ if (!(str_list_copy(&search_attrs, (char **) attrs)))
{
rc = LDAP_NO_MEMORY;
goto done;
@@ -671,7 +494,7 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res,
const char *exp,
const char **attrs)
{
- return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
+ return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE,
exp, attrs, res);
}
@@ -982,11 +805,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname)))
goto done;
- if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm)))
+ if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->realm)))
goto done;
ou_str = ads_ou_string(org_unit);
new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str,
- ads->config.bind_path);
+ ads->bind_path);
free(ou_str);
if (!new_dn)
goto done;
@@ -1102,7 +925,6 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area)
} handlers[] = {
{"objectGUID", False, dump_binary},
{"nTSecurityDescriptor", False, dump_sd},
- {"dnsRecord", False, dump_binary},
{"objectSid", False, dump_sid},
{NULL, True, NULL}
};
@@ -1177,7 +999,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res,
char *field;
BOOL string;
- pull_utf8_talloc(ctx, &field, utf8_field);
+ pull_utf8_talloc(ctx, (void **) &field, utf8_field);
string = fn(field, NULL, data_area);
if (string) {
@@ -1239,7 +1061,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org
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));
+ host, ads->realm));
return status;
}
}
@@ -1402,15 +1224,20 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
char *host = strdup(hostname);
char *principal;
+ if (!ads->kdc_server) {
+ DEBUG(0, ("Unable to find KDC server\n"));
+ return ADS_ERROR(LDAP_SERVER_DOWN);
+ }
+
strlower(host);
/*
we need to use the '$' form of the name here, as otherwise the
server might end up setting the password for a user instead
*/
- asprintf(&principal, "%s$@%s", host, ads->auth.realm);
+ asprintf(&principal, "%s$@%s", host, ads->realm);
- status = krb5_set_password(ads->auth.kdc_server, principal, password);
+ status = krb5_set_password(ads->kdc_server, principal, password);
free(host);
free(principal);
@@ -1460,7 +1287,7 @@ char *ads_pull_string(ADS_STRUCT *ads,
if (!values) return NULL;
if (values[0]) {
- rc = pull_utf8_talloc(mem_ctx, &ux_string,
+ rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string,
values[0]);
if (rc != -1)
ret = ux_string;
@@ -1494,7 +1321,7 @@ char **ads_pull_strings(ADS_STRUCT *ads,
ret = talloc(mem_ctx, sizeof(char *) * (n+1));
for (i=0;i<n;i++) {
- if (pull_utf8_talloc(mem_ctx, &ret[i], values[i]) == -1) {
+ if (pull_utf8_talloc(mem_ctx, (void **)&ret[i], values[i]) == -1) {
return NULL;
}
}
@@ -1645,27 +1472,33 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
return ADS_ERROR(LDAP_DECODING_ERROR);
}
- SAFE_FREE(ads->config.ldap_server_name);
+ SAFE_FREE(ads->ldap_server_name);
- ads->config.ldap_server_name = strdup(p+1);
- p = strchr(ads->config.ldap_server_name, '$');
+ ads->ldap_server_name = strdup(p+1);
+ p = strchr(ads->ldap_server_name, '$');
if (!p || p[1] != '@') {
ldap_value_free(values);
ldap_msgfree(res);
- SAFE_FREE(ads->config.ldap_server_name);
+ SAFE_FREE(ads->ldap_server_name);
return ADS_ERROR(LDAP_DECODING_ERROR);
}
*p = 0;
- SAFE_FREE(ads->config.realm);
- SAFE_FREE(ads->config.bind_path);
+ SAFE_FREE(ads->server_realm);
+ SAFE_FREE(ads->bind_path);
- ads->config.realm = strdup(p+2);
- ads->config.bind_path = ads_build_dn(ads->config.realm);
+ ads->server_realm = strdup(p+2);
+ ads->bind_path = ads_build_dn(ads->server_realm);
+
+ /* in case the realm isn't configured in smb.conf */
+ if (!ads->realm || !ads->realm[0]) {
+ SAFE_FREE(ads->realm);
+ ads->realm = strdup(ads->server_realm);
+ }
DEBUG(3,("got ldap server name %s@%s\n",
- ads->config.ldap_server_name, ads->config.realm));
+ ads->ldap_server_name, ads->realm));
return ADS_SUCCESS;
}
@@ -1681,13 +1514,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
* @return the count of SIDs pulled
**/
ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
- int *num_trusts,
- char ***names,
- char ***alt_names,
- DOM_SID **sids)
+ int *num_trusts, char ***names, DOM_SID **sids)
{
- const char *attrs[] = {"name", "flatname", "securityIdentifier",
- "trustDirection", NULL};
+ const char *attrs[] = {"flatName", "securityIdentifier", NULL};
ADS_STATUS status;
void *res, *msg;
int count, i;
@@ -1704,31 +1533,11 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
}
(*names) = talloc(mem_ctx, sizeof(char *) * count);
- (*alt_names) = talloc(mem_ctx, sizeof(char *) * count);
(*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count);
if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY);
for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
- uint32 direction;
-
- /* direction is a 2 bit bitfield, 1 means they trust us
- but we don't trust them, so we should not list them
- as users from that domain can't login */
- if (ads_pull_uint32(ads, msg, "trustDirection", &direction) &&
- direction == 1) {
- continue;
- }
-
- (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name");
- (*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname");
-
- if ((*alt_names)[i] && (*alt_names)[i][0]) {
- /* we prefer the flatname as the primary name
- for consistency with RPC */
- char *name = (*alt_names)[i];
- (*alt_names)[i] = (*names)[i];
- (*names)[i] = name;
- }
+ (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName");
if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) {
i++;
}
@@ -1753,7 +1562,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
void *res;
ADS_STATUS rc;
- rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)",
+ rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)",
attrs, &res);
if (!ADS_ERR_OK(rc)) return rc;
if (!ads_pull_sid(ads, res, "objectSid", sid)) {
@@ -1764,66 +1573,4 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
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
-*/
-ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup)
-{
- char *exp;
- ADS_STATUS rc;
- char **principles;
- char *prefix;
- int prefix_length;
- int i;
- void *res;
- const char *attrs[] = {"servicePrincipalName", NULL};
-
- (*workgroup) = NULL;
-
- asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))",
- ads->config.ldap_server_name, ads->config.realm);
- rc = ads_search(ads, &res, exp, attrs);
- free(exp);
-
- if (!ADS_ERR_OK(rc)) {
- return rc;
- }
-
- principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName");
-
- 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 (strncasecmp(principles[i], prefix, prefix_length) == 0 &&
- strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 &&
- !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/source3/libads/ldap_user.c b/source3/libads/ldap_user.c
index b6fef24b5c..b6e3d189c5 100644
--- a/source3/libads/ldap_user.c
+++ b/source3/libads/ldap_user.c
@@ -55,10 +55,10 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user,
status = ADS_ERROR(LDAP_NO_MEMORY);
- if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm)))
+ if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->realm)))
goto done;
if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", name,
- ads->config.bind_path)))
+ ads->bind_path)))
goto done;
if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT)))
goto done;
@@ -94,7 +94,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group,
status = ADS_ERROR(LDAP_NO_MEMORY);
if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group,
- ads->config.bind_path)))
+ ads->bind_path)))
goto done;
if (!(mods = ads_init_mods(ctx)))
goto done;
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index 81dedb0a81..1b55453cac 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -77,7 +77,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
/* 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);
+ asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm);
krb5_init_context(&ctx);
krb5_set_default_tgs_ktypes(ctx, enc_types);
krb5_parse_name(ctx, sname, &principal);
@@ -163,7 +163,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
gss_release_buffer(&minor_status, &output_token);
- output_token.value = malloc(strlen(ads->config.bind_path) + 8);
+ output_token.value = malloc(strlen(ads->bind_path) + 8);
p = output_token.value;
*p++ = 1; /* no sign or seal */
@@ -171,10 +171,9 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
*p++ = max_msg_size>>16;
*p++ = max_msg_size>>8;
*p++ = max_msg_size;
- snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
- p += strlen(ads->config.bind_path);
+ snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path);
- output_token.length = strlen(ads->config.bind_path) + 8;
+ output_token.length = strlen(ads->bind_path) + 8;
gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
&output_token, &conf_state,
diff --git a/source3/libads/util.c b/source3/libads/util.c
index b10b130a31..d48eb10b71 100644
--- a/source3/libads/util.c
+++ b/source3/libads/util.c
@@ -39,7 +39,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip
new_password = strdup(tmp_password);
asprintf(&service_principal, "HOST/%s", host_principal);
- ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password,
+ ret = kerberos_set_password(ads->kdc_server, host_principal, password,
service_principal, new_password);
if (!secrets_store_machine_password(new_password)) {
diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c
new file mode 100644
index 0000000000..7fc27b9c3b
--- /dev/null
+++ b/source3/libsmb/cli_dfs.c
@@ -0,0 +1,245 @@
+/*
+ Unix SMB/CIFS implementation.
+ RPC pipe client
+ 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"
+
+/* Query DFS support */
+
+NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL *dfs_exists)
+{
+ prs_struct qbuf, rbuf;
+ DFS_Q_DFS_EXIST q;
+ DFS_R_DFS_EXIST 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);
+
+ /* Marshall data and send request */
+
+ init_dfs_q_dfs_exist(&q);
+
+ if (!dfs_io_q_dfs_exist("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, DFS_EXIST, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!dfs_io_r_dfs_exist("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return result */
+
+ *dfs_exists = (r.status != 0);
+
+ result = NT_STATUS_OK;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename,
+ char *comment, uint32 flags)
+{
+ prs_struct qbuf, rbuf;
+ DFS_Q_DFS_ADD q;
+ DFS_R_DFS_ADD 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);
+
+ /* Marshall data and send request */
+
+ init_dfs_q_dfs_add(&q, entrypath, servername, sharename, comment,
+ flags);
+
+ if (!dfs_io_q_dfs_add("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, DFS_ADD, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!dfs_io_r_dfs_add("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return result */
+
+ result = werror_to_ntstatus(r.status);
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename)
+{
+ prs_struct qbuf, rbuf;
+ DFS_Q_DFS_REMOVE q;
+ DFS_R_DFS_REMOVE 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);
+
+ /* Marshall data and send request */
+
+ init_dfs_q_dfs_remove(&q, entrypath, servername, sharename);
+
+ if (!dfs_io_q_dfs_remove("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, DFS_REMOVE, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!dfs_io_r_dfs_remove("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return result */
+
+ result = werror_to_ntstatus(r.status);
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename,
+ uint32 info_level, DFS_INFO_CTR *ctr)
+
+{
+ prs_struct qbuf, rbuf;
+ DFS_Q_DFS_GET_INFO q;
+ DFS_R_DFS_GET_INFO 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);
+
+ /* Marshall data and send request */
+
+ init_dfs_q_dfs_get_info(&q, entrypath, servername, sharename,
+ info_level);
+
+ if (!dfs_io_q_dfs_get_info("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, DFS_GET_INFO, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!dfs_io_r_dfs_get_info("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return result */
+
+ result = werror_to_ntstatus(r.status);
+ *ctr = r.ctr;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Enumerate dfs shares */
+
+NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 info_level, DFS_INFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ DFS_Q_DFS_ENUM q;
+ DFS_R_DFS_ENUM 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);
+
+ /* Marshall data and send request */
+
+ init_dfs_q_dfs_enum(&q, info_level, ctr);
+
+ if (!dfs_io_q_dfs_enum("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, DFS_ENUM, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ r.ctr = ctr;
+
+ if (!dfs_io_r_dfs_enum("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return result */
+
+ result = werror_to_ntstatus(r.status);
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c
new file mode 100644
index 0000000000..7dfee46fae
--- /dev/null
+++ b/source3/libsmb/cli_lsarpc.c
@@ -0,0 +1,1168 @@
+/*
+ Unix SMB/CIFS implementation.
+ RPC pipe client
+ Copyright (C) Tim Potter 2000-2001,
+ 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
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the 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"
+
+/** @defgroup lsa LSA - Local Security Architecture
+ * @ingroup rpc_client
+ *
+ * @{
+ **/
+
+/**
+ * @file cli_lsarpc.c
+ *
+ * RPC client routines for the LSA RPC pipe. LSA means "local
+ * security authority", which is half of a password database.
+ **/
+
+/** Open a LSA policy handle
+ *
+ * @param cli Handle on an initialised SMB connection */
+
+NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL sec_qos, uint32 des_access, POLICY_HND *pol)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_OPEN_POL q;
+ LSA_R_OPEN_POL r;
+ LSA_SEC_QOS qos;
+ 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 */
+
+ if (sec_qos) {
+ init_lsa_sec_qos(&qos, 2, 1, 0);
+ init_q_open_pol(&q, '\\', 0, des_access, &qos);
+ } else {
+ init_q_open_pol(&q, '\\', 0, des_access, NULL);
+ }
+
+ /* Marshall data and send request */
+
+ if (!lsa_io_q_open_pol("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (NT_STATUS_IS_OK(result = r.status)) {
+ *pol = r.pol;
+#ifdef __INSURE__
+ pol->marker = malloc(1);
+#endif
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Open a LSA policy handle
+ *
+ * @param cli Handle on an initialised SMB connection
+ */
+
+NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL sec_qos, uint32 des_access, POLICY_HND *pol)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_OPEN_POL2 q;
+ LSA_R_OPEN_POL2 r;
+ LSA_SEC_QOS qos;
+ 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 */
+
+ if (sec_qos) {
+ init_lsa_sec_qos(&qos, 2, 1, 0);
+ init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access,
+ &qos);
+ } else {
+ init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access,
+ NULL);
+ }
+
+ /* Marshall data and send request */
+
+ if (!lsa_io_q_open_pol2("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_OPENPOLICY2, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_open_pol2("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (NT_STATUS_IS_OK(result = r.status)) {
+ *pol = r.pol;
+#ifdef __INSURE__
+ pol->marker = (char *)malloc(1);
+#endif
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Close a LSA policy handle */
+
+NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_CLOSE q;
+ LSA_R_CLOSE 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);
+
+ /* Marshall data and send request */
+
+ init_lsa_q_close(&q, pol);
+
+ if (!lsa_io_q_close("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_close("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (NT_STATUS_IS_OK(result = r.status)) {
+#ifdef __INSURE__
+ SAFE_FREE(pol->marker);
+#endif
+ *pol = r.pol;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Lookup a list of sids */
+
+NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, int num_sids, DOM_SID *sids,
+ char ***domains, char ***names, uint32 **types)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_LOOKUP_SIDS q;
+ LSA_R_LOOKUP_SIDS r;
+ DOM_R_REF ref;
+ LSA_TRANS_NAME_ENUM t_names;
+ 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_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1);
+
+ if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ ZERO_STRUCT(ref);
+ ZERO_STRUCT(t_names);
+
+ r.dom_ref = &ref;
+ r.names = &t_names;
+
+ if (!lsa_io_r_lookup_sids("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = r.status;
+
+ if (!NT_STATUS_IS_OK(result) &&
+ NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
+
+ /* An actual error occured */
+
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (r.mapped_count == 0) {
+ result = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) *
+ num_sids))) {
+ DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) *
+ num_sids))) {
+ DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) *
+ num_sids))) {
+ DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ for (i = 0; i < num_sids; i++) {
+ fstring name, dom_name;
+ uint32 dom_idx = t_names.name[i].domain_idx;
+
+ /* Translate optimised name through domain index array */
+
+ 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]);
+
+ (*names)[i] = talloc_strdup(mem_ctx, name);
+ (*domains)[i] = talloc_strdup(mem_ctx, dom_name);
+ (*types)[i] = t_names.name[i].sid_name_use;
+
+ if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) {
+ DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ } else {
+ (*names)[i] = NULL;
+ (*types)[i] = SID_NAME_UNKNOWN;
+ }
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Lookup a list of names */
+
+NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, int num_names,
+ const char **names, DOM_SID **sids,
+ uint32 **types)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_LOOKUP_NAMES q;
+ LSA_R_LOOKUP_NAMES r;
+ DOM_R_REF ref;
+ 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_lookup_names(mem_ctx, &q, pol, num_names, names);
+
+ if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ ZERO_STRUCT(ref);
+ r.dom_ref = &ref;
+
+ if (!lsa_io_r_lookup_names("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = r.status;
+
+ if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
+ NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
+
+ /* An actual error occured */
+
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (r.mapped_count == 0) {
+ result = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) *
+ num_names)))) {
+ DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) *
+ num_names)))) {
+ DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ for (i = 0; i < num_names; i++) {
+ DOM_RID2 *t_rids = r.dom_rid;
+ uint32 dom_idx = t_rids[i].rid_idx;
+ uint32 dom_rid = t_rids[i].rid;
+ DOM_SID *sid = &(*sids)[i];
+
+ /* Translate optimised sid through domain index array */
+
+ if (dom_idx != 0xffffffff) {
+
+ sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
+
+ if (dom_rid != 0xffffffff) {
+ sid_append_rid(sid, dom_rid);
+ }
+
+ (*types)[i] = t_rids[i].type;
+ } else {
+ ZERO_STRUCTP(sid);
+ (*types)[i] = SID_NAME_UNKNOWN;
+ }
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Query info policy
+ *
+ * @param domain_sid - returned remote server's domain sid */
+
+NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint16 info_class,
+ fstring domain_name, DOM_SID *domain_sid)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_QUERY_INFO q;
+ LSA_R_QUERY_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);
+
+ /* Marshall data and send request */
+
+ init_q_query(&q, pol, info_class);
+
+ if (!lsa_io_q_query("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_query("", &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_sid);
+ domain_name[0] = '\0';
+
+ switch (info_class) {
+
+ case 3:
+ if (r.dom.id3.buffer_dom_name != 0) {
+ unistr2_to_ascii(domain_name,
+ &r.dom.id3.
+ uni_domain_name,
+ sizeof (fstring) - 1);
+ }
+
+ if (r.dom.id3.buffer_dom_sid != 0) {
+ *domain_sid = r.dom.id3.dom_sid.sid;
+ }
+
+ break;
+
+ case 5:
+
+ if (r.dom.id5.buffer_dom_name != 0) {
+ unistr2_to_ascii(domain_name, &r.dom.id5.
+ uni_domain_name,
+ sizeof (fstring) - 1);
+ }
+
+ 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;
+ }
+
+ 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
+ **/
+
+NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_ctx,
+ uint32 *pref_num_domains, uint32 *num_domains,
+ char ***domain_names, DOM_SID **domain_sids)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_ENUM_TRUST_DOM q;
+ LSA_R_ENUM_TRUST_DOM 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_trust_dom(&q, pol, *enum_ctx, *pref_num_domains);
+
+ if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_enum_trust_dom("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ 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)) {
+
+ /* An actual error ocured */
+
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (r.num_domains) {
+
+ /* Allocate memory for trusted domain names and sids */
+
+ *domain_names = (char **)talloc(mem_ctx, sizeof(char *) *
+ r.num_domains);
+
+ if (!*domain_names) {
+ DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ *domain_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) *
+ r.num_domains);
+ if (!domain_sids) {
+ DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Copy across names and sids */
+
+ for (i = 0; i < r.num_domains; i++) {
+ fstring tmp;
+
+ unistr2_to_ascii(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);
+ }
+ }
+
+ *num_domains = r.num_domains;
+ *enum_ctx = r.enum_context;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Enumerate privileges*/
+
+NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
+ uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_ENUM_PRIVS q;
+ LSA_R_ENUM_PRIVS 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_privs(&q, pol, *enum_context, pref_max_length);
+
+ if (!lsa_io_q_enum_privs("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_ENUM_PRIVS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_enum_privs("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ *enum_context = r.enum_context;
+ *count = r.count;
+
+ if (!((*privs_name = (char **)talloc(mem_ctx, sizeof(char *) * r.count)))) {
+ DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!((*privs_high = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) {
+ DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!((*privs_low = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) {
+ DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ for (i = 0; i < r.count; i++) {
+ fstring name;
+
+ rpcstr_pull_unistr2_fstring( name, &r.privs[i].name);
+
+ (*privs_name)[i] = talloc_strdup(mem_ctx, name);
+
+ (*privs_high)[i] = r.privs[i].luid_high;
+ (*privs_low)[i] = r.privs[i].luid_low;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Get privilege name */
+
+NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys,
+ fstring description, uint16 *lang_id_desc)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_PRIV_GET_DISPNAME q;
+ LSA_R_PRIV_GET_DISPNAME 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);
+
+ /* Marshall data and send request */
+
+ init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
+
+ if (!lsa_io_q_priv_get_dispname("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_priv_get_dispname("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ rpcstr_pull_unistr2_fstring(description , &r.desc);
+ *lang_id_desc = r.lang_id;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Enumerate list of SIDs */
+
+NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length,
+ uint32 *num_sids, DOM_SID **sids)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_ENUM_ACCOUNTS q;
+ LSA_R_ENUM_ACCOUNTS 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_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
+
+ if (!lsa_io_q_enum_accounts("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_enum_accounts("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = r.status;
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ if (r.sids.num_entries==0)
+ goto done;
+
+ /* Return output parameters */
+
+ *sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.sids.num_entries);
+ if (!*sids) {
+ DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Copy across names and sids */
+
+ for (i = 0; i < r.sids.num_entries; i++) {
+ sid_copy(&(*sids)[i], &r.sids.sid[i].sid);
+ }
+
+ *num_sids= r.sids.num_entries;
+ *enum_ctx = r.enum_context;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Open a LSA user handle
+ *
+ * @param cli Handle on an initialised SMB connection */
+
+NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access,
+ POLICY_HND *user_pol)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_OPENACCOUNT q;
+ LSA_R_OPENACCOUNT 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_open_account(&q, dom_pol, sid, des_access);
+
+ /* Marshall data and send request */
+
+ if (!lsa_io_q_open_account("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_OPENACCOUNT, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_open_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;
+}
+
+/** Enumerate user privileges
+ *
+ * @param cli Handle on an initialised SMB connection */
+
+NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *count, LUID_ATTR **set)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_ENUMPRIVSACCOUNT q;
+ LSA_R_ENUMPRIVSACCOUNT 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);
+
+ /* Initialise input parameters */
+
+ init_lsa_q_enum_privsaccount(&q, pol);
+
+ /* Marshall data and send request */
+
+ if (!lsa_io_q_enum_privsaccount("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_enum_privsaccount("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ if (r.count == 0)
+ goto done;
+
+ if (!((*set = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR) * r.count)))) {
+ DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ 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;
+ }
+
+ *count=r.count;
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Get a privilege value given its name */
+
+NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char *name, LUID *luid)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_LOOKUPPRIVVALUE q;
+ LSA_R_LOOKUPPRIVVALUE 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);
+
+ /* Marshall data and send request */
+
+ init_lsa_q_lookupprivvalue(&q, pol, name);
+
+ if (!lsa_io_q_lookupprivvalue("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_LOOKUPPRIVVALUE, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_lookupprivvalue("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ (*luid).low=r.luid.low;
+ (*luid).high=r.luid.high;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Query LSA security object */
+
+NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 sec_info,
+ SEC_DESC_BUF **psdb)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_QUERY_SEC_OBJ q;
+ LSA_R_QUERY_SEC_OBJ 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);
+
+ /* Marshall data and send request */
+
+ init_q_query_sec_obj(&q, pol, sec_info);
+
+ if (!lsa_io_q_query_sec_obj("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_QUERYSECOBJ, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_query_sec_obj("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (psdb)
+ *psdb = r.buf;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ 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. */
+
+BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid)
+{
+ extern pstring global_myname;
+ struct cli_state cli;
+ NTSTATUS result;
+ POLICY_HND lsa_pol;
+ BOOL ret = False;
+
+ ZERO_STRUCT(cli);
+ if(cli_initialise(&cli) == False) {
+ DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n"));
+ return False;
+ }
+
+ if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
+ DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine));
+ goto done;
+ }
+
+ if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
+ DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
+ DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n",
+ remote_machine));
+ goto done;
+ }
+
+ cli.protocol = PROTOCOL_NT1;
+
+ if (!cli_negprot(&cli)) {
+ DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ if (cli.protocol != PROTOCOL_NT1) {
+ DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n",
+ remote_machine));
+ goto done;
+ }
+
+ /*
+ * Do an anonymous session setup.
+ */
+
+ if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+ DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ if (!(cli.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
+ DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
+ remote_machine));
+ goto done;
+ }
+
+ if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+ DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ /* Fetch domain sid */
+
+ if (!cli_nt_session_open(&cli, PIPE_LSARPC)) {
+ DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
+ goto done;
+ }
+
+ 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) ));
+ 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) ));
+ goto done;
+ }
+
+ ret = True;
+
+ done:
+
+ cli_shutdown(&cli);
+ return ret;
+}
+
+#endif
+
+/** @} **/
diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c
new file mode 100644
index 0000000000..d32e0e77e4
--- /dev/null
+++ b/source3/libsmb/cli_netlogon.c
@@ -0,0 +1,664 @@
+/*
+ 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"
+
+/* 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",
+ 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;
+}
+
+/****************************************************************************
+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(1,("cli_nt_setup_creds: auth2 challenge failed %s\n",
+ nt_errstr(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,
+ char *username, 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;
+ extern pstring global_myname;
+ NET_ID_INFO_CTR ctr;
+ NET_USER_INFO_3 user;
+ int validation_level = 3;
+
+ 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);
+
+ 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(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,
+ 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, &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 *username, const char *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;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ 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, 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, &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;
+}
+
+/***************************************************************************
+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;
+}
+
diff --git a/source3/libsmb/cli_pipe_util.c b/source3/libsmb/cli_pipe_util.c
new file mode 100644
index 0000000000..de1c832e44
--- /dev/null
+++ b/source3/libsmb/cli_pipe_util.c
@@ -0,0 +1,82 @@
+/*
+ Unix SMB/CIFS implementation.
+ 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"
+
+/** \defgroup rpc_client RPC Client routines
+ */
+
+/* Opens a SMB connection to a named pipe */
+
+struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name,
+ 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/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c
new file mode 100644
index 0000000000..aaf18882f7
--- /dev/null
+++ b/source3/libsmb/cli_reg.c
@@ -0,0 +1,102 @@
+/*
+ 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
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the 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_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+ const char *msg, uint32 timeout, uint16 flags)
+{
+ prs_struct qbuf;
+ prs_struct rbuf;
+ REG_Q_SHUTDOWN q_s;
+ REG_R_SHUTDOWN 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_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))
+ goto done;
+
+ /* Unmarshall response */
+
+ if(reg_io_r_shutdown("", &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_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_ABORT_SHUTDOWN q_s;
+ REG_R_ABORT_SHUTDOWN 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_reg_q_abort_shutdown(&q_s);
+
+ if (!reg_io_q_abort_shutdown("", &q_s, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, REG_ABORT_SHUTDOWN, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0))
+ result = r_s.status;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf );
+
+ return result;
+}
diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c
new file mode 100644
index 0000000000..91577b3325
--- /dev/null
+++ b/source3/libsmb/cli_samr.c
@@ -0,0 +1,1294 @@
+/*
+ Unix SMB/CIFS implementation.
+ RPC pipe client
+ Copyright (C) Tim Potter 2000-2001,
+ 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.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the 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"
+
+/* Connect to SAMR database */
+
+NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 access_mask, POLICY_HND *connect_pol)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_CONNECT q;
+ SAMR_R_CONNECT 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ 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;
+}
+
+/* Close SAMR handle */
+
+NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *connect_pol)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_CLOSE_HND q;
+ SAMR_R_CLOSE_HND 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ 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;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Open handle on a domain */
+
+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)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_OPEN_DOMAIN q;
+ SAMR_R_OPEN_DOMAIN 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ 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:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Open handle on a user */
+
+NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 user_rid, POLICY_HND *user_pol)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_OPEN_USER q;
+ SAMR_R_OPEN_USER 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ 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:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Open handle on a group */
+
+NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 group_rid, POLICY_HND *group_pol)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_OPEN_GROUP q;
+ SAMR_R_OPEN_GROUP 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ 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:
+ 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,
+ POLICY_HND *user_pol, uint16 switch_value,
+ SAM_USERINFO_CTR **ctr)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_USERINFO q;
+ SAMR_R_QUERY_USERINFO 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+ *ctr = r.ctr;
+
+ 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,
+ POLICY_HND *group_pol, uint32 info_level,
+ GROUP_INFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_GROUPINFO q;
+ SAMR_R_QUERY_GROUPINFO 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ r.ctr = ctr;
+
+ if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Query user groups */
+
+NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint32 *num_groups,
+ DOM_GID **gid)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_USERGROUPS q;
+ SAMR_R_QUERY_USERGROUPS 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ if (NT_STATUS_IS_OK(result = r.status)) {
+ *num_groups = r.num_entries;
+ *gid = r.gid;
+ }
+
+ 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,
+ POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **als_rids)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_USERALIASES q;
+ SAMR_R_QUERY_USERALIASES r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ unsigned int ptr=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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ if (NT_STATUS_IS_OK(result = r.status)) {
+ *num_aliases = r.num_entries;
+ *als_rids = r.rid;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Query user groups */
+
+NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *group_pol, uint32 *num_mem,
+ uint32 **rid, uint32 **attr)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_GROUPMEM q;
+ SAMR_R_QUERY_GROUPMEM 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);
+
+ /* Marshall data and send request */
+
+ 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))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ if (NT_STATUS_IS_OK(result = r.status)) {
+ *num_mem = r.num_entries;
+ *rid = r.rid;
+ *attr = r.attr;
+ }
+
+ 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,
+ POLICY_HND *pol, uint32 *start_idx,
+ uint32 size, struct acct_info **dom_groups,
+ uint32 *num_dom_groups)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_ENUM_DOM_GROUPS q;
+ SAMR_R_ENUM_DOM_GROUPS r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 name_idx, 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_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))
+ goto done;
+
+ /* Unmarshall response */
+
+ 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))
+ goto done;
+
+ *num_dom_groups = r.num_entries2;
+
+ if (!((*dom_groups) = (struct acct_info *)
+ talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
+
+ name_idx = 0;
+
+ for (i = 0; i < *num_dom_groups; i++) {
+
+ (*dom_groups)[i].rid = r.sam[i].rid;
+
+ if (r.sam[i].hdr_name.buffer) {
+ unistr2_to_ascii((*dom_groups)[i].acct_name,
+ &r.uni_grp_name[name_idx],
+ sizeof(fstring) - 1);
+ name_idx++;
+ }
+
+ *start_idx = r.next_idx;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Enumerate domain groups */
+
+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_groups,
+ uint32 *num_dom_groups)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_ENUM_DOM_ALIASES q;
+ SAMR_R_ENUM_DOM_ALIASES r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 name_idx, 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_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
+
+ if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_enum_dom_aliases("", &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)) {
+ goto done;
+ }
+
+ *num_dom_groups = r.num_entries2;
+
+ if (!((*dom_groups) = (struct acct_info *)
+ talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
+
+ name_idx = 0;
+
+ for (i = 0; i < *num_dom_groups; i++) {
+
+ (*dom_groups)[i].rid = r.sam[i].rid;
+
+ if (r.sam[i].hdr_name.buffer) {
+ unistr2_to_ascii((*dom_groups)[i].acct_name,
+ &r.uni_grp_name[name_idx],
+ sizeof(fstring) - 1);
+ name_idx++;
+ }
+
+ *start_idx = r.next_idx;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Query alias members */
+
+NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *alias_pol, uint32 *num_mem,
+ DOM_SID **sids)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_ALIASMEM q;
+ SAMR_R_QUERY_ALIASMEM r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 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_samr_q_query_aliasmem(&q, alias_pol);
+
+ if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ *num_mem = r.num_sids;
+
+ if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ for (i = 0; i < *num_mem; i++) {
+ (*sids)[i] = r.sid[i].sid;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Open handle on an alias */
+
+NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 alias_rid, POLICY_HND *alias_pol)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_OPEN_ALIAS q;
+ SAMR_R_OPEN_ALIAS 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);
+
+ /* Marshall data and send request */
+
+ init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
+
+ if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ 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;
+}
+
+/* Query domain info */
+
+NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_DOMAIN_INFO q;
+ SAMR_R_QUERY_DOMAIN_INFO 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);
+
+ /* Marshall data and send request */
+
+ init_samr_q_query_dom_info(&q, domain_pol, switch_value);
+
+ if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ r.ctr = ctr;
+
+ if (!samr_io_r_query_dom_info("", &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;
+}
+
+/* Query display info */
+
+NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 *start_idx,
+ uint16 switch_value, uint32 *num_entries,
+ uint32 max_entries, SAM_DISPINFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_DISPINFO q;
+ SAMR_R_QUERY_DISPINFO 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);
+
+ /* Marshall data and send request */
+
+ init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
+ *start_idx, max_entries);
+
+ if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ r.ctr = ctr;
+
+ if (!samr_io_r_query_dispinfo("", &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)) {
+ goto done;
+ }
+
+ *num_entries = r.num_entries;
+ *start_idx += r.num_entries; /* No next_idx in this structure! */
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
+ looked up in one packet. */
+
+NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_rids, uint32 *rids,
+ uint32 *num_names, char ***names,
+ uint32 **name_types)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_LOOKUP_RIDS q;
+ SAMR_R_LOOKUP_RIDS r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 i;
+
+ 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"));
+ }
+
+ 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_rids(mem_ctx, &q, domain_pol, flags,
+ num_rids, rids);
+
+ if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ if (r.num_names1 == 0) {
+ *num_names = 0;
+ *names = NULL;
+ goto done;
+ }
+
+ *num_names = r.num_names1;
+ *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
+ *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
+
+ for (i = 0; i < r.num_names1; i++) {
+ fstring tmp;
+
+ unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
+ (*names)[i] = talloc_strdup(mem_ctx, tmp);
+ (*name_types)[i] = r.type[i];
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Lookup names */
+
+NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_names, const char **names,
+ uint32 *num_rids, uint32 **rids,
+ uint32 **rid_types)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_LOOKUP_NAMES q;
+ SAMR_R_LOOKUP_NAMES r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 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_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
+ num_names, names);
+
+ if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ if (r.num_rids1 == 0) {
+ *num_rids = 0;
+ goto done;
+ }
+
+ *num_rids = r.num_rids1;
+ *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
+ *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
+
+ for (i = 0; i < r.num_rids1; i++) {
+ (*rids)[i] = r.rids[i];
+ (*rid_types)[i] = r.types[i];
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* 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,
+ uint32 acb_info, uint32 unknown,
+ POLICY_HND *user_pol, uint32 *rid)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_CREATE_USER q;
+ SAMR_R_CREATE_USER 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);
+
+ /* Marshall data and send request */
+
+ init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
+
+ if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ if (user_pol)
+ *user_pol = r.user_pol;
+
+ if (rid)
+ *rid = r.user_rid;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Set userinfo */
+
+NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ 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;
+
+ 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 */
+
+ q.ctr = ctr;
+
+ init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
+ ctr->info.id);
+
+ if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_set_userinfo("", &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;
+}
+
+/* Set userinfo2 */
+
+NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ 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;
+
+ 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_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
+
+ if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_set_userinfo2("", &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;
+}
+
+/* Delete domain user */
+
+NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_DELETE_DOM_USER q;
+ SAMR_R_DELETE_DOM_USER 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);
+
+ /* Marshall data and send request */
+
+ init_samr_q_delete_dom_user(&q, user_pol);
+
+ if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Query user security object */
+
+NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_SEC_OBJ q;
+ SAMR_R_QUERY_SEC_OBJ 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);
+
+ /* Marshall data and send request */
+
+ init_samr_q_query_sec_obj(&q, user_pol, switch_value);
+
+ if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ result = r.status;
+ *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ 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, uint16 *unk_2)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_GET_DOM_PWINFO q;
+ SAMR_R_GET_DOM_PWINFO 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);
+
+ /* 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;
+ if (unk_2)
+ *unk_2 = r.unk_2;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c
new file mode 100644
index 0000000000..18e17758d6
--- /dev/null
+++ b/source3/libsmb/cli_spoolss.c
@@ -0,0 +1,2156 @@
+/*
+ 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.
+*/
+
+#include "includes.h"
+
+/** @defgroup spoolss SPOOLSS - NT printing routines
+ * @ingroup rpc_client
+ *
+ * @{
+ **/
+
+/**********************************************************************
+ Initialize a new spoolss buff for use by a client rpc
+**********************************************************************/
+static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
+{
+ buffer->ptr = (size != 0);
+ buffer->size = size;
+ buffer->string_at_end = size;
+ prs_init(&buffer->prs, size, ctx, MARSHALL);
+ buffer->struct_start = prs_offset(&buffer->prs);
+}
+
+/*********************************************************************
+ Decode various spoolss rpc's and info levels
+ ********************************************************************/
+
+/**********************************************************************
+**********************************************************************/
+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));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ smb_io_printer_info_0("", buffer, &inf[i], 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+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));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ smb_io_printer_info_1("", buffer, &inf[i], 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 returned, PRINTER_INFO_2 **info)
+{
+ uint32 i;
+ PRINTER_INFO_2 *inf;
+
+ inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ /* a little initialization as we go */
+ inf[i].secdesc = NULL;
+ smb_io_printer_info_2("", buffer, &inf[i], 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 returned, PRINTER_INFO_3 **info)
+{
+ uint32 i;
+ PRINTER_INFO_3 *inf;
+
+ inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ inf[i].secdesc = NULL;
+ smb_io_printer_info_3("", buffer, &inf[i], 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 returned, PORT_INFO_1 **info)
+{
+ uint32 i;
+ PORT_INFO_1 *inf;
+
+ inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
+
+ prs_set_offset(&buffer->prs, 0);
+
+ for (i=0; i<returned; i++) {
+ smb_io_port_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 returned, PORT_INFO_2 **info)
+{
+ uint32 i;
+ PORT_INFO_2 *inf;
+
+ inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
+
+ prs_set_offset(&buffer->prs, 0);
+
+ for (i=0; i<returned; i++) {
+ smb_io_port_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 returned, DRIVER_INFO_1 **info)
+{
+ uint32 i;
+ DRIVER_INFO_1 *inf;
+
+ inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 returned, DRIVER_INFO_2 **info)
+{
+ uint32 i;
+ DRIVER_INFO_2 *inf;
+
+ inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 returned, DRIVER_INFO_3 **info)
+{
+ uint32 i;
+ DRIVER_INFO_3 *inf;
+
+ inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+**********************************************************************/
+static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 returned, DRIVER_DIRECTORY_1 **info
+)
+{
+ DRIVER_DIRECTORY_1 *inf;
+
+ inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
+
+ prs_set_offset(&buffer->prs, 0);
+
+ smb_io_driverdir_1("", buffer, inf, 0);
+
+ *info=inf;
+}
+
+/** Return a handle to the specified printer or print server.
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ *
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param printername The name of the printer or print server to be
+ * opened in UNC format.
+ *
+ * @param datatype Specifies the default data type for the printer.
+ *
+ * @param access_required The access rights requested on the printer or
+ * print server.
+ *
+ * @param station The UNC name of the requesting workstation.
+ *
+ * @param username The name of the user requesting the open.
+ *
+ * @param pol Returned policy handle.
+ */
+
+/*********************************************************************************
+ Win32 API - OpenPrinter()
+ ********************************************************************************/
+
+WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *printername, char *datatype, uint32 access_required,
+ char *station, char *username, POLICY_HND *pol)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_OPEN_PRINTER_EX q;
+ SPOOL_R_OPEN_PRINTER_EX 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_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) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ if (W_ERROR_IS_OK(result))
+ *pol = r.handle;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Close a printer handle
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ *
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param pol Policy handle of printer or print server to close.
+ */
+/*********************************************************************************
+ Win32 API - ClosePrinter()
+ ********************************************************************************/
+
+WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_CLOSEPRINTER q;
+ SPOOL_R_CLOSEPRINTER 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_closeprinter(&q, pol);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ if (W_ERROR_IS_OK(result))
+ *pol = r.handle;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Enumerate printers on a print server.
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param offered Buffer size offered in the request.
+ * @param needed Number of bytes needed to complete the request.
+ * may be NULL.
+ *
+ * @param flags Selected from PRINTER_ENUM_* flags.
+ * @param level Request information level.
+ *
+ * @param num_printers Pointer to number of printers returned. May be
+ * NULL.
+ * @param ctr Return structure for printer information. May
+ * be NULL.
+ */
+/*********************************************************************************
+ Win32 API - EnumPrinters()
+ ********************************************************************************/
+
+WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ uint32 flags, uint32 level,
+ uint32 *num_printers, PRINTER_INFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ENUMPRINTERS q;
+ SPOOL_R_ENUMPRINTERS r;
+ NEW_BUFFER buffer;
+ WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", 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);
+
+ make_spoolss_q_enumprinters(&q, flags, server, level, &buffer,
+ offered);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ 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;
+
+ 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);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - EnumPorts()
+ ********************************************************************************/
+/** Enumerate printer ports on a print server.
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param offered Buffer size offered in the request.
+ * @param needed Number of bytes needed to complete the request.
+ * May be NULL.
+ *
+ * @param level Requested information level.
+ *
+ * @param num_ports Pointer to number of ports returned. May be NULL.
+ * @param ctr Pointer to structure holding port information.
+ * May be NULL.
+ */
+
+WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ uint32 level, int *num_ports, PORT_INFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ENUMPORTS q;
+ SPOOL_R_ENUMPORTS r;
+ NEW_BUFFER buffer;
+ WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", 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);
+
+ make_spoolss_q_enumports(&q, server, level, &buffer, offered);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
+ if (needed)
+ *needed = r.needed;
+ }
+
+ result = r.status;
+
+ /* Return output parameters */
+
+ if (!W_ERROR_IS_OK(result))
+ goto done;
+
+ if (num_ports)
+ *num_ports = r.returned;
+
+ 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);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - GetPrinter()
+ ********************************************************************************/
+
+WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ POLICY_HND *pol, uint32 level,
+ PRINTER_INFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_GETPRINTER q;
+ SPOOL_R_GETPRINTER r;
+ NEW_BUFFER buffer;
+ WERROR result = W_ERROR(ERRgeneral);
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* 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);
+
+ 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;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_getprinter("", &r, &rbuf, 0))
+ goto done;
+
+ if (needed)
+ *needed = r.needed;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ 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);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - SetPrinter()
+ ********************************************************************************/
+/** Set printer info
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param pol Policy handle on printer to set info.
+ * @param level Information level to set.
+ * @param ctr Pointer to structure holding printer information.
+ * @param command Specifies the action performed. See
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp
+ * 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)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_SETPRINTER q;
+ SPOOL_R_SETPRINTER 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_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))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
+ goto done;
+
+ result = r.status;
+
+done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - GetPrinterDriver()
+ ********************************************************************************/
+/** Get installed printer drivers for a given printer
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ *
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param offered Buffer size offered in the request.
+ * @param needed Number of bytes needed to complete the request.
+ * may be NULL.
+ *
+ * @param pol Pointer to an open policy handle for the printer
+ * opened with cli_spoolss_open_printer_ex().
+ * @param level Requested information level.
+ * @param env The print environment or archictecture. This is
+ * "Windows NT x86" for NT4.
+ * @param ctr Returned printer driver information.
+ */
+
+WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ POLICY_HND *pol, uint32 level,
+ char *env, PRINTER_DRIVER_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_GETPRINTERDRIVER2 q;
+ SPOOL_R_GETPRINTERDRIVER2 r;
+ NEW_BUFFER buffer;
+ WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ 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);
+
+ 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;
+
+ /* Unmarshall response */
+
+ if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) {
+ if (needed)
+ *needed = r.needed;
+ }
+
+ result = r.status;
+
+ /* Return output parameters */
+
+ if (!W_ERROR_IS_OK(result))
+ goto done;
+
+ if (!ctr)
+ 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;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - EnumPrinterDrivers()
+ ********************************************************************************/
+/**********************************************************************
+ * Get installed printer drivers for a given printer
+ */
+WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ uint32 level, char *env,
+ uint32 *num_drivers,
+ PRINTER_DRIVER_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ENUMPRINTERDRIVERS q;
+ SPOOL_R_ENUMPRINTERDRIVERS r;
+ NEW_BUFFER buffer;
+ WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", 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);
+
+ /* Write the request */
+
+ make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer,
+ offered);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0))
+ goto done;
+
+ if (needed)
+ *needed = r.needed;
+
+ if (num_drivers)
+ *num_drivers = r.returned;
+
+ result = r.status;
+
+ /* 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;
+ }
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+
+/*********************************************************************************
+ Win32 API - GetPrinterDriverDirectory()
+ ********************************************************************************/
+/**********************************************************************
+ * Get installed printer drivers for a given printer
+ */
+WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ uint32 level, char *env,
+ DRIVER_DIRECTORY_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_GETPRINTERDRIVERDIR q;
+ SPOOL_R_GETPRINTERDRIVERDIR r;
+ NEW_BUFFER buffer;
+ WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", 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);
+
+ /* Write the request */
+
+ make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer,
+ offered);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
+ &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) {
+ if (needed)
+ *needed = r.needed;
+ }
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ if (W_ERROR_IS_OK(result)) {
+ switch (level) {
+ case 1:
+ decode_printerdriverdir_1(mem_ctx, r.buffer, 1,
+ &ctr->info1);
+ break;
+ }
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - AddPrinterDriver()
+ ********************************************************************************/
+/**********************************************************************
+ * Install a printer driver
+ */
+WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, uint32 level,
+ PRINTER_DRIVER_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ADDPRINTERDRIVER q;
+ SPOOL_R_ADDPRINTERDRIVER r;
+ WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ 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);
+
+ /* Write the request */
+
+ make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - AddPrinter()
+ ********************************************************************************/
+/**********************************************************************
+ * Install a printer
+ */
+WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 level, PRINTER_INFO_CTR*ctr)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ADDPRINTEREX q;
+ SPOOL_R_ADDPRINTEREX r;
+ WERROR result = W_ERROR(ERRgeneral);
+ fstring server,
+ client,
+ user;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ 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);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Write the request */
+
+ make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user,
+ level, ctr);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - DeltePrinterDriver()
+ ********************************************************************************/
+/**********************************************************************
+ * Delete a Printer Driver from the server (does not remove
+ * the driver files
+ */
+WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, char *arch,
+ char *driver)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_DELETEPRINTERDRIVER q;
+ SPOOL_R_DELETEPRINTERDRIVER r;
+ WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
+
+ 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);
+
+ slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (server);
+
+ /* Write the request */
+
+ make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/*********************************************************************************
+ Win32 API - GetPrinterProcessorDirectory()
+ ********************************************************************************/
+
+WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ char *name, char *environment,
+ fstring procdir)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_GETPRINTPROCESSORDIRECTORY q;
+ SPOOL_R_GETPRINTPROCESSORDIRECTORY r;
+ int level = 1;
+ WERROR result = W_ERROR(ERRgeneral);
+ NEW_BUFFER buffer;
+
+ 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_buffer(&buffer, offered, mem_ctx);
+
+ make_spoolss_q_getprintprocessordirectory(
+ &q, name, environment, level, &buffer, offered);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
+ &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ if (needed)
+ *needed = r.needed;
+
+ if (W_ERROR_IS_OK(result))
+ fstrcpy(procdir, "Not implemented!");
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Add a form to a printer.
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param handle Policy handle opened with cli_spoolss_open_printer_ex
+ * or cli_spoolss_addprinterex.
+ * @param level Form info level to add - should always be 1.
+ * @param form A pointer to the form to be added.
+ *
+ */
+
+WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle, uint32 level, FORM *form)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ADDFORM q;
+ SPOOL_R_ADDFORM 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_addform(&q, handle, level, form);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_addform("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_addform("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Set a form on a printer.
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param handle Policy handle opened with cli_spoolss_open_printer_ex
+ * or cli_spoolss_addprinterex.
+ * @param level Form info level to set - should always be 1.
+ * @param form A pointer to the form to be set.
+ *
+ */
+
+WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle, uint32 level, char *form_name,
+ FORM *form)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_SETFORM q;
+ SPOOL_R_SETFORM 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_setform(&q, handle, level, form_name, form);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_setform("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_setform("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ if (!W_ERROR_IS_OK(result))
+ goto done;
+
+
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Get a form on a printer.
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param handle Policy handle opened with cli_spoolss_open_printer_ex
+ * or cli_spoolss_addprinterex.
+ * @param formname Name of the form to get
+ * @param level Form info level to get - should always be 1.
+ *
+ */
+
+WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ POLICY_HND *handle, char *formname, uint32 level,
+ FORM_1 *form)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_GETFORM q;
+ SPOOL_R_GETFORM 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_getform(&q, handle, formname, level, &buffer, offered);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_getform("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_getform("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ if (needed)
+ *needed = r.needed;
+
+ if (W_ERROR_IS_OK(result))
+ smb_io_form_1("", r.buffer, form, 0);
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Delete a form on a printer.
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param handle Policy handle opened with cli_spoolss_open_printer_ex
+ * or cli_spoolss_addprinterex.
+ * @param form The name of the form to delete.
+ *
+ */
+
+WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle, char *form_name)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_DELETEFORM q;
+ SPOOL_R_DELETEFORM 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_deleteform(&q, handle, form_name);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_deleteform("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+ uint32 num_forms, FORM_1 **forms)
+{
+ int i;
+
+ *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1));
+ buffer->prs.data_offset = 0;
+
+ for (i = 0; i < num_forms; i++)
+ smb_io_form_1("", buffer, &((*forms)[i]), 0);
+}
+
+/** Enumerate forms
+ *
+ * @param cli Pointer to client state structure which is open
+ * on the SPOOLSS pipe.
+ * @param mem_ctx Pointer to an initialised talloc context.
+ *
+ * @param offered Buffer size offered in the request.
+ * @param needed Number of bytes needed to complete the request.
+ * may be NULL.
+ * or cli_spoolss_addprinterex.
+ * @param level Form info level to get - should always be 1.
+ * @param handle Open policy handle
+ *
+ */
+
+WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 offered, uint32 *needed,
+ POLICY_HND *handle, int level, uint32 *num_forms,
+ FORM_1 **forms)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ENUMFORMS q;
+ SPOOL_R_ENUMFORMS 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_enumforms(&q, handle, level, &buffer, offered);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_enumforms("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ if (needed)
+ *needed = r.needed;
+
+ if (num_forms)
+ *num_forms = r.numofforms;
+
+ decode_forms_1(mem_ctx, r.buffer, *num_forms, forms);
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ 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));
+ buffer->prs.data_offset = 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));
+ buffer->prs.data_offset = 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, char *valuename,
+ uint32 *data_type, char **data,
+ uint32 *data_size)
+{
+ 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 */
+
+ if (data_type)
+ *data_type = r.type;
+
+ if (data) {
+ *data = (char *)talloc(mem_ctx, r.needed);
+ memcpy(*data, r.data, r.needed);
+ }
+
+ if (data_size)
+ *data_size = r.needed;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Set printer data */
+
+WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, char *value,
+ uint32 data_type, char *data,
+ uint32 data_size)
+{
+ 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, data, data_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;
+}
+
+/* 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,
+ char **value, uint32 *data_type, char **data,
+ uint32 *data_size)
+{
+ 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 (data_type)
+ *data_type = r.type;
+
+ if (value) {
+ fstring the_value;
+
+ rpcstr_pull(the_value, r.value, sizeof(the_value), -1,
+ STR_TERMINATE);
+
+ *value = talloc_strdup(mem_ctx, the_value);
+ }
+
+ if (data)
+ *data = talloc_memdup(mem_ctx, r.data, r.realdatasize);
+
+ if (data_size)
+ *data_size = r.realdatasize;
+
+ 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);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_writeprinter("", &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;
+}
+
+/** @} **/
diff --git a/source3/libsmb/cli_spoolss_notify.c b/source3/libsmb/cli_spoolss_notify.c
new file mode 100644
index 0000000000..922b0fbb1d
--- /dev/null
+++ b/source3/libsmb/cli_spoolss_notify.c
@@ -0,0 +1,223 @@
+/*
+ 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.
+*/
+
+#include "includes.h"
+
+/*
+ * SPOOLSS Client RPC's used by servers as the notification
+ * 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. */
+
+WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *printer, uint32 printerlocal, 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_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return result */
+
+ memcpy(handle, &r.handle, sizeof(r.handle));
+ result = r.status;
+
+done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Close a back-channel notification connection */
+
+WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *handle)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_REPLYCLOSEPRINTER q;
+ SPOOL_R_REPLYCLOSEPRINTER r;
+ WERROR result = W_ERROR(ERRgeneral);
+
+ /* Initialise input parameters */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ make_spoolss_q_reply_closeprinter(&q, handle);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return result */
+
+ result = r.status;
+
+done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/*********************************************************************
+ This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change
+ notification event when the registration **did not** use
+ SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor.
+ 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)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_ROUTERREPLYPRINTER q;
+ SPOOL_R_ROUTERREPLYPRINTER r;
+ WERROR result = W_ERROR(ERRgeneral);
+
+ /* 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 */
+
+ if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0))
+ goto done;
+
+ /* Return output parameters */
+
+ result = r.status;
+
+done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/*********************************************************************
+ This SPOOLSS_REPLY_RRPCN 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)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_REPLY_RRPCN q;
+ SPOOL_R_REPLY_RRPCN r;
+ WERROR result = W_ERROR(ERRgeneral);
+ SPOOL_NOTIFY_INFO notify_info;
+
+ 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);
+
+ ZERO_STRUCT(notify_info);
+
+ /* Initialise input parameters */
+
+ notify_info.version = 0x2;
+ notify_info.flags = 0x00020000; /* ?? */
+ notify_info.count = notify_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 */
+
+ if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0))
+ goto done;
+
+ if (r.unknown0 == 0x00080000)
+ DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n"));
+
+ result = r.status;
+
+done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c
new file mode 100644
index 0000000000..2dc12d726c
--- /dev/null
+++ b/source3/libsmb/cli_srvsvc.c
@@ -0,0 +1,442 @@
+/*
+ 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 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"
+
+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;
+}
+
+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);
+
+ 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, strlen(s) + 1);
+
+ 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, strlen(s) + 1);
+
+ }
+
+ 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, strlen(s) + 1);
+
+ 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, strlen(s) + 1);
+
+ 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, strlen(s) + 1);
+
+ 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, strlen(s) + 1);
+ }
+ 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,
+ char *netname, uint32 type, char *remark,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ char *path, 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, 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, strlen(s) + 1);
+
+ 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, strlen(s) + 1);
+
+ }
+
+ 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/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c
new file mode 100644
index 0000000000..97b948bf62
--- /dev/null
+++ b/source3/libsmb/cli_wkssvc.c
@@ -0,0 +1,93 @@
+/*
+ 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/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 93cf3d95db..472db69fd0 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -54,6 +54,9 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user,
return False;
}
+ /* Lanman2 cannot use SMB signing. */
+ cli->sign_info.use_smb_signing = False;
+
/* if in share level security then don't send a password now */
if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
passlen = 0;
@@ -206,11 +209,12 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, 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);
- p += clistr_push(cli, p, pword, -1, STR_TERMINATE); /* password */
- SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
+ memcpy(p, pword, passlen);
+ p += passlen;
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);
@@ -253,12 +257,11 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
char *workgroup)
{
uint32 capabilities = cli_session_setup_capabilities(cli);
- uchar pword[24];
- uchar ntpword[24];
+ fstring pword, ntpword;
char *p;
BOOL tried_signing = False;
- if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) {
+ if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
return False;
}
@@ -266,21 +269,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
/* non encrypted password supplied. Ignore ntpass. */
passlen = 24;
ntpasslen = 24;
- SMBencrypt(pass,cli->secblob.data,pword);
- SMBNTencrypt(pass,cli->secblob.data,ntpword);
+ SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword);
+ SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword);
if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) {
- cli_calculate_mac_key(cli, pass, ntpword);
+ cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword);
tried_signing = True;
}
} else {
- /* pre-encrypted password supplied. Only used for security=server, can't do
- signing becouse we don't have oringial key */
- memcpy(pword, pass, 24);
- if (ntpasslen == 24) {
- memcpy(ntpword, ntpass, 24);
- } else {
- ZERO_STRUCT(ntpword);
- }
+ memcpy(pword, pass, passlen);
+ memcpy(ntpword, ntpass, ntpasslen);
}
/* send a session setup command */
@@ -308,13 +305,8 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
cli_setup_bcc(cli, p);
cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- if (tried_signing) {
- /* We only use it if we have a successful non-guest connect */
- cli->sign_info.use_smb_signing = False;
- }
+ if (!cli_receive_smb(cli))
return False;
- }
show_msg(cli->inbuf);
@@ -490,8 +482,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user,
/* encrypt the password with the challenge */
memcpy(challenge, chal1.data + 24, 8);
- SMBencrypt(pass, challenge,lmhash);
- SMBNTencrypt(pass, challenge,nthash);
+ SMBencrypt((unsigned char *)pass, challenge,lmhash);
+ SMBNTencrypt((unsigned char *)pass, challenge,nthash);
#if 0
file_save("nthash.dat", nthash, 24);
@@ -1070,7 +1062,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
}
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;
}
@@ -1190,8 +1182,9 @@ again:
if (!cli_session_setup(cli, user, password, strlen(password)+1,
password, strlen(password)+1,
domain)) {
- if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK)
- && cli_session_setup(cli, "", "", 0, "", 0, 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)));
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
index 16702c375b..469b946088 100644
--- a/source3/libsmb/clispnego.c
+++ b/source3/libsmb/clispnego.c
@@ -2,7 +2,6 @@
Unix SMB/CIFS implementation.
simple kerberos5/SPNEGO routines
Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jim McDonough 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
@@ -440,28 +439,6 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
return True;
}
-/*
- generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much.
-*/
-DATA_BLOB spnego_gen_auth_response(void)
-{
- ASN1_DATA data;
- DATA_BLOB ret;
-
- memset(&data, 0, sizeof(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, 0);
- asn1_pop_tag(&data);
- asn1_pop_tag(&data);
- asn1_pop_tag(&data);
-
- ret = data_blob(data.data, data.length);
- asn1_free(&data);
- return ret;
-}
/*
this is a tiny msrpc packet generator. I am only using this to
@@ -472,7 +449,6 @@ DATA_BLOB spnego_gen_auth_response(void)
format specifiers are:
U = unicode string (input is unix string)
- a = address (1 byte type, 1 byte length, unicode string, all inline)
B = data blob (pointer + length)
b = data blob in header (pointer + length)
d = word (4 bytes)
@@ -497,11 +473,6 @@ BOOL msrpc_gen(DATA_BLOB *blob,
head_size += 8;
data_size += str_charnum(s) * 2;
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;
@@ -541,19 +512,6 @@ BOOL msrpc_gen(DATA_BLOB *blob,
push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN);
data_ofs += n*2;
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);
@@ -592,7 +550,6 @@ BOOL msrpc_gen(DATA_BLOB *blob,
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)
@@ -627,24 +584,6 @@ BOOL msrpc_parse(DATA_BLOB *blob,
STR_UNICODE|STR_NOALIGN);
(*ps) = strdup(p);
break;
- case 'A':
- 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;
- }
- ps = va_arg(ap, char **);
- if (0 < len1) {
- pull_string(NULL, p, blob->data + ptr, -1,
- len1, STR_ASCII|STR_NOALIGN);
- (*ps) = strdup(p);
- } else {
- (*ps) = NULL;
- }
- break;
case 'B':
len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 40a353fa8b..18564bccf4 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -170,11 +170,6 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
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)));
@@ -196,7 +191,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
if (i == count)
goto done;
- pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
+ pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE);
result = True;
done:
@@ -216,7 +211,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
/*
comparison function used by sort_ip_list
*/
-int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
+static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
{
int max_bits1=0, max_bits2=0;
int num_interfaces = iface_count();
@@ -278,11 +273,6 @@ 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;
}
@@ -566,11 +556,6 @@ BOOL name_resolve_bcast(const char *name, int name_type,
int sock, i;
int num_interfaces = iface_count();
- if (lp_disable_netbios()) {
- DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
- return False;
- }
-
*return_ip_list = NULL;
*return_count = 0;
@@ -617,11 +602,6 @@ BOOL resolve_wins(const char *name, int name_type,
char **wins_tags;
struct in_addr src_ip;
- if (lp_disable_netbios()) {
- DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
- return False;
- }
-
*return_iplist = NULL;
*return_count = 0;
@@ -783,7 +763,7 @@ static BOOL resolve_hosts(const char *name,
*********************************************************/
static BOOL internal_resolve_name(const char *name, int name_type,
- struct in_addr **return_iplist, int *return_count)
+ struct in_addr **return_iplist, int *return_count)
{
pstring name_resolve_list;
fstring tok;
@@ -816,15 +796,6 @@ static BOOL internal_resolve_name(const char *name, int name_type,
return True;
}
- /* Check netbios name cache */
-
- if (namecache_fetch(name, name_type, return_iplist, return_count)) {
-
- /* This could be a negative response */
-
- return (*return_count > 0);
- }
-
pstrcpy(name_resolve_list, lp_name_resolve_order());
ptr = name_resolve_list;
if (!ptr || !*ptr)
@@ -832,16 +803,9 @@ static BOOL internal_resolve_name(const char *name, int name_type,
while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
if((strequal(tok, "host") || strequal(tok, "hosts"))) {
- if (name_type == 0x20) {
- if (resolve_hosts(name, return_iplist, return_count)) {
- result = True;
- goto done;
- } else {
-
- /* Store negative lookup result */
-
- namecache_store(name, name_type, 0, NULL);
- }
+ if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
+ result = True;
+ goto done;
}
} else if(strequal( tok, "lmhosts")) {
if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
@@ -913,10 +877,6 @@ static BOOL internal_resolve_name(const char *name, int name_type,
*return_iplist = nodupes_iplist;
*return_count = nodupes_count;
}
-
- /* Save in name cache */
-
- namecache_store(name, name_type, *return_count, *return_iplist);
/* Display some debugging info */
@@ -970,16 +930,11 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
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 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)) {
*master_ip = ip_list[0];
SAFE_FREE(ip_list);
@@ -1002,14 +957,10 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
BOOL lookup_dc_name(const char *srcname, const char *domain,
struct in_addr *dc_ip, char *ret_name)
{
-#if !defined(I_HATE_WINDOWS_REPLY_CODE)
+#if !defined(I_HATE_WINDOWS_REPLY_CODE)
+
fstring dc_name;
BOOL ret;
-
- if (lp_disable_netbios()) {
- DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
- return False;
- }
/*
* Due to the fact win WinNT *sucks* we must do a node status
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index dfa355a7ec..95434d0ae4 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -28,7 +28,7 @@
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])
+void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24)
{
uchar p21[21];
@@ -66,9 +66,9 @@ void E_md4hash(const char *passwd, uchar p16[16])
}
/**
- * Creates the DES forward-only Hash of the users password in DOS ASCII charset
+ * Creates the MD4 Hash of the users password in NT UNICODE.
* @param passwd password in 'unix' charset.
- * @param p16 return password hashed with DES, caller allocated 16 byte buffer
+ * @param p16 return password hashed with md4, caller allocated 16 byte buffer
*/
void E_deshash(const char *passwd, uchar p16[16])
@@ -77,7 +77,7 @@ void E_deshash(const char *passwd, uchar p16[16])
ZERO_STRUCT(dospwd);
ZERO_STRUCTP(p16);
- /* Password must be converted to DOS charset - null terminated, uppercase. */
+ /* Password must be converted to DOS charset - null terminated. */
push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
E_P16(dospwd, p16);
@@ -175,7 +175,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];
@@ -226,14 +226,14 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
void SMBOWFencrypt_ntv2(const uchar kr[16],
const DATA_BLOB srv_chal,
const DATA_BLOB cli_chal,
- uchar resp_buf[16])
+ char 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);
+ hmac_md5_final((unsigned char *)resp_buf, &ctx);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
@@ -337,7 +337,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
SMB signing - setup the MAC key.
************************************************************/
-void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uchar resp[24])
+void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24])
{
/* Get first 16 bytes. */
E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]);
diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c
index fe6b673e39..3b77f7330e 100644
--- a/source3/libsmb/trust_passwd.c
+++ b/source3/libsmb/trust_passwd.c
@@ -35,7 +35,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_
unsigned char new_trust_passwd_hash[16])
{
NTSTATUS result;
- result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash);
if (!NT_STATUS_IS_OK(result)) {
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index c86ee69a09..6c2f8de3b1 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -122,7 +122,6 @@ void kill_async_dns_child(void)
{
if (child_pid > 0) {
kill(child_pid, SIGTERM);
- child_pid = -1;
}
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 05ea4997d5..d30efb550c 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -269,8 +269,9 @@ static BOOL reload_interfaces(time_t t)
static BOOL reload_nmbd_services(BOOL test)
{
BOOL ret;
+ extern fstring remote_machine;
- set_remote_machine_name("nmbd");
+ fstrcpy( remote_machine, "nmbd" );
if ( lp_loaded() ) {
pstring fname;
@@ -860,10 +861,8 @@ static void usage(char *pname)
DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
- if ( !open_sockets( is_daemon, global_nmb_port ) ) {
- kill_async_dns_child();
+ if ( !open_sockets( is_daemon, global_nmb_port ) )
return 1;
- }
/* Determine all the IP addresses we have. */
load_interfaces();
@@ -872,7 +871,6 @@ static void usage(char *pname)
if( False == create_subnets() )
{
DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
- kill_async_dns_child();
exit(1);
}
@@ -884,7 +882,6 @@ static void usage(char *pname)
if( !initialise_wins() )
{
DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
- kill_async_dns_child();
exit(1);
}
@@ -899,7 +896,6 @@ static void usage(char *pname)
if( False == register_my_workgroup_and_names() )
{
DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
- kill_async_dns_child();
exit(1);
}
@@ -910,6 +906,5 @@ static void usage(char *pname)
if (dbf)
x_fclose(dbf);
- kill_async_dns_child();
return(0);
}
diff --git a/source3/nmbd/nmbd_become_dmb.c b/source3/nmbd/nmbd_become_dmb.c
index ccc1f7e8ad..7f4a7a2144 100644
--- a/source3/nmbd/nmbd_become_dmb.c
+++ b/source3/nmbd/nmbd_become_dmb.c
@@ -347,7 +347,7 @@ static void become_domain_master_browser_wins(char *workgroup_name)
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));
diff --git a/source3/nmbd/nmbd_mynames.c b/source3/nmbd/nmbd_mynames.c
index ba7d509a77..345245c57d 100644
--- a/source3/nmbd/nmbd_mynames.c
+++ b/source3/nmbd/nmbd_mynames.c
@@ -225,7 +225,7 @@ void refresh_my_names(time_t t)
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);
+ namerec->data.refresh_time = t + MIN(lp_max_ttl(), MAX_REFRESH_TIME);
}
}
}
diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c
index b6d3c20d99..4ac5473d4a 100644
--- a/source3/nmbd/nmbd_nameregister.c
+++ b/source3/nmbd/nmbd_nameregister.c
@@ -106,7 +106,17 @@ static void register_name_response(struct subnet_record *subrec,
success = False;
} else {
/* Unicast - check to see if the response allows us to have the name. */
- if (nmb->header.opcode == NMB_WACK_OPCODE) {
+ 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 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. */
@@ -118,16 +128,6 @@ static void register_name_response(struct subnet_record *subrec,
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. */
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index d252b98ed6..a20ebf16fd 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -705,33 +705,14 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
{
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)
+ subrec->bcast_ip)) == NULL)
return NULL;
if(lp_bind_interfaces_only()) {
@@ -1689,7 +1670,7 @@ void retransmit_or_expire_response_records(time_t t)
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_time += rrec->repeat_interval;
rrec->repeat_count--;
}
else
@@ -1969,7 +1950,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
/* Setup the smb part. */
ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
memcpy(tmp,ptr,4);
- set_message(ptr,17,23 + len,True);
+ set_message(ptr,17,17 + len,True);
memcpy(ptr,tmp,4);
SCVAL(ptr,smb_com,SMBtrans);
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index d6605d08f5..23e4f935ca 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -4,8 +4,6 @@
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
Copyright (C) Jeremy Allison 1994-1998
- Copyright (C) Jim McDonough 2002
- Copyright (C) Anthony Liguori 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
@@ -286,108 +284,19 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
/* 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, global_myworkgroup,sizeof(pstring), True);
- }
-#ifdef HAVE_ADS
- else {
- GUID domain_guid;
- pstring domain;
- char *component, *dc, *q1;
- uint8 size;
-
- safe_strcpy(domain, lp_realm(), sizeof(domain));
-
- if (SVAL(uniuser, 0) == 0) {
- SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
- } else {
- SSVAL(q, 0, SAMLOGON_AD_R);
- }
- q += 2;
-
- SSVAL(q, 0, 0);
- q += 2;
- 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;
- }
- memcpy(q, &domain_guid, sizeof(domain_guid));
- q += sizeof(domain_guid);
-
- /* Push domain components */
- dc = domain;
- q1 = q;
- while ((component = strsep(&dc, "."))) {
- size = push_ascii(&q[1], component, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- }
- SCVAL(q, 0, 0); q++;
- SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
- q += 2; /* it must follow the domain name. */
-
- /* Push dns host name */
- size = push_ascii(&q[1], global_myname, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
- q += 2; /* it must follow the domain name. */
-
- /* Push NETBIOS of domain */
- size = push_ascii(&q[1], domain, -1, STR_UPPER);
- SCVAL(q, 0, size);
- q += (size + 1);
- SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */
- /* null terminator would not be needed because size is included */
-
- /* Push NETBIOS of hostname */
- size = push_ascii(&q[1], my_name, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
- SCVAL(q, 0, 0); q++; /* null terminator or empty field? */
-
- /* Push user account */
- size = push_ascii(&q[1], ascuser, -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- /* Push 'Default-First-Site-Name' */
- size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
- SCVAL(q, 0, size);
- q += (size + 1);
-
- SSVAL(q, 0, 0xc000); /* unknown */
- SCVAL(q, 2, PTR_DIFF(q,q1));
- SCVAL(q, 3, 0x10); /* unknown */
- q += 4;
-
- 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
+ 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, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13);
- /* our ntversion */
+ SIVAL(q, 0, 1); /* our ntversion */
SSVAL(q, 4, 0xffff); /* our lmnttoken */
SSVAL(q, 6, 0xffff); /* our lm20token */
q += 8;
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index 29ceca4e79..4739cfbf7a 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -79,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;
@@ -163,10 +163,6 @@ static int winbind_auth_request(const char *user, const char *pass, int ctrl)
/* 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)
@@ -245,12 +241,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;
diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c
index 9ac1515d7d..bcb339864a 100644
--- a/source3/nsswitch/wb_client.c
+++ b/source3/nsswitch/wb_client.c
@@ -65,7 +65,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)
{
@@ -102,7 +102,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;
@@ -168,7 +168,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;
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
index 9bc9faafb5..89dd625241 100644
--- a/source3/nsswitch/wb_common.c
+++ b/source3/nsswitch/wb_common.c
@@ -28,6 +28,7 @@
/* 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 */
@@ -39,6 +40,16 @@ 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)
@@ -314,6 +325,12 @@ NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
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) {
ZERO_STRUCT(lrequest);
request = &lrequest;
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index 4d36acc51b..d0af10a0e6 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -255,7 +255,8 @@ static BOOL wbinfo_check_secret(void)
ZERO_STRUCT(response);
- result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response);
+ result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response) ==
+ NSS_STATUS_SUCCESS;
d_printf("checking the trust secret via RPC calls %s\n",
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
@@ -489,9 +490,9 @@ static BOOL wbinfo_auth_crap(char *username)
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;
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index 256c0203c0..358d9add3a 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -25,7 +25,7 @@
/* List of all connected clients */
-static struct winbindd_cli_state *client_list;
+struct winbindd_cli_state *client_list;
static int num_clients;
BOOL opt_nocache = False;
BOOL opt_dual_daemon = False;
@@ -375,9 +375,6 @@ void winbind_process_packet(struct winbindd_cli_state *state)
{
/* Process request */
- /* Ensure null termination of entire request */
- state->request.domain[sizeof(state->request.domain)-1]='\0';
-
state->pid = state->request.pid;
process_request(state);
@@ -691,8 +688,6 @@ int winbind_setup_common(void)
}
- namecache_enable(); /* Enable netbios namecache */
-
/* 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. */
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index dd92ecefe6..11d399be49 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -88,7 +88,7 @@ typedef struct {
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 */
/* Lookup methods for this domain (LDAP or RPC) */
@@ -170,15 +170,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 */
@@ -194,8 +190,6 @@ typedef struct {
#include "rpc_client.h"
#define WINBINDD_ESTABLISH_LOOP 30
-#define WINBINDD_RESCAN_FREQ 300
-
#define DOM_SEQUENCE_NONE ((uint32)-1)
/* SETENV */
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index b0b70178a4..b61348adfe 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -61,8 +61,8 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope
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)));
+ DEBUG(3,("Reopening ads connection to %s after error %s\n",
+ ads->ldap_server, ads_errstr(status)));
if (ads->ld) {
ldap_unbind(ads->ld);
}
@@ -87,7 +87,7 @@ ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
const char *exp,
const char **attrs)
{
- return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
+ return ads_do_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE,
exp, attrs, res);
}
@@ -108,6 +108,8 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
ADS_STRUCT *ads;
ADS_STATUS status;
char *ccache;
+ struct in_addr server_ip;
+ char *sname;
if (domain->private) {
return (ADS_STRUCT *)domain->private;
@@ -118,23 +120,30 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
SETENV("KRB5CCNAME", ccache, 1);
unlink(ccache);
- ads = ads_init(domain->alt_name, domain->name, NULL);
+ if (resolve_name(domain->name, &server_ip, 0x1b)) {
+ sname = inet_ntoa(server_ip);
+ } else if (resolve_name(domain->name, &server_ip, 0x1c)) {
+ sname = inet_ntoa(server_ip);
+ } else {
+ if (strcasecmp(domain->name, lp_workgroup()) != 0) {
+ DEBUG(1,("can't find domain controller for %s\n", domain->name));
+ return NULL;
+ }
+ sname = NULL;
+ }
+
+ ads = ads_init(primary_realm, domain->name, NULL, NULL, 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();
-
- if (primary_realm) {
- SAFE_FREE(ads->auth.realm);
- ads->auth.realm = strdup(primary_realm);
- }
+ SAFE_FREE(ads->password);
+ ads->password = secrets_fetch_machine_password();
status = ads_connect(ads);
- if (!ADS_ERR_OK(status) || !ads->config.realm) {
+ if (!ADS_ERR_OK(status) || !ads->realm) {
extern struct winbindd_methods msrpc_methods;
DEBUG(1,("ads_connect for domain %s failed: %s\n",
domain->name, ads_errstr(status)));
@@ -152,9 +161,11 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
/* remember our primary realm for trusted domain support */
if (!primary_realm) {
- primary_realm = strdup(ads->config.realm);
+ primary_realm = strdup(ads->realm);
}
+ fstrcpy(domain->full_name, ads->server_realm);
+
domain->private = (void *)ads;
return ads;
}
@@ -394,7 +405,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
/* accept either the win2000 or the pre-win2000 username */
asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
- name, name, ads->config.realm);
+ name, name, ads->realm);
rc = ads_search_retry(ads, &res, exp, attrs);
free(exp);
if (!ADS_ERR_OK(rc)) {
@@ -524,6 +535,49 @@ failed:
return False;
}
+
+/* convert a sid to a distnguished name */
+static NTSTATUS sid_to_distinguished_name(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ DOM_SID *sid,
+ char **dn)
+{
+ ADS_STRUCT *ads = NULL;
+ const char *attrs[] = {"distinguishedName", NULL};
+ ADS_STATUS rc;
+ void *msg = NULL;
+ char *exp;
+ char *sidstr;
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+
+ DEBUG(3,("ads: sid_to_distinguished_name\n"));
+
+ ads = ads_cached_connection(domain);
+ if (!ads) goto done;
+
+ sidstr = sid_binstring(sid);
+ asprintf(&exp, "(objectSid=%s)", sidstr);
+ rc = ads_search_retry(ads, &msg, exp, attrs);
+ free(exp);
+ free(sidstr);
+ if (!ADS_ERR_OK(rc)) {
+ DEBUG(1,("sid_to_distinguished_name ads_search: %s\n", ads_errstr(rc)));
+ goto done;
+ }
+
+ *dn = ads_pull_string(ads, mem_ctx, msg, "distinguishedName");
+
+ status = NT_STATUS_OK;
+
+ DEBUG(3,("ads sid_to_distinguished_name mapped %s\n", *dn));
+
+done:
+ if (msg) ads_msgfree(ads, msg);
+
+ return status;
+}
+
+
/* Lookup user information from a rid */
static NTSTATUS query_user(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
@@ -777,7 +831,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
- char ***alt_names,
DOM_SID **dom_sids)
{
ADS_STRUCT *ads;
@@ -789,7 +842,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
ads = ads_cached_connection(domain);
if (!ads) return NT_STATUS_UNSUCCESSFUL;
- rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids);
+ rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, dom_sids);
return ads_ntstatus(rc);
}
@@ -814,37 +867,6 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
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;
- char *workgroup;
-
- ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
-
- if (!(ctx = talloc_init_named("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(domain->alt_name);
- strupper(domain->name);
- }
-
- talloc_destroy(ctx);
-
- return ads_ntstatus(rc);
-}
-
/* the ADS backend methods are exposed via this structure */
struct winbindd_methods ads_methods = {
True,
@@ -857,8 +879,7 @@ struct winbindd_methods ads_methods = {
lookup_groupmem,
sequence_number,
trusted_domains,
- domain_sid,
- alternate_name
+ domain_sid
};
#endif
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 060139af3e..a607727867 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -873,14 +873,13 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
- char ***alt_names,
DOM_SID **dom_sids)
{
struct winbind_cache *cache = get_cache(domain);
/* we don't cache this call */
return cache->backend->trusted_domains(domain, mem_ctx, num_domains,
- names, alt_names, dom_sids);
+ names, dom_sids);
}
/* find the domain sid */
@@ -892,15 +891,6 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
return cache->backend->domain_sid(domain, sid);
}
-/* find the alternate names for the domain, if any */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- struct winbind_cache *cache = get_cache(domain);
-
- /* we don't cache this call */
- return cache->backend->alternate_name(domain);
-}
-
/* the ADS backend methods are exposed via this structure */
struct winbindd_methods cache_methods = {
True,
@@ -913,6 +903,5 @@ struct winbindd_methods cache_methods = {
lookup_groupmem,
sequence_number,
trusted_domains,
- domain_sid,
- alternate_name
+ domain_sid
};
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 2dec9f0558..3ab97ed408 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -90,122 +90,12 @@ struct get_dc_name_cache {
struct get_dc_name_cache *prev, *next;
};
-
-/*
- find the DC for a domain using methods appropriate for a ADS domain
-*/
-static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
-{
- ADS_STRUCT *ads;
- const char *realm = domain;
-
- if (strcasecmp(realm, lp_workgroup()) == 0) {
- realm = lp_realm();
- }
-
- ads = ads_init(realm, domain, NULL);
- if (!ads) {
- return False;
- }
-
- /* we don't need to bind, just connect */
- ads->auth.no_bind = 1;
-
- DEBUG(4,("cm_ads_find_dc: domain=%s\n", domain));
-
-#ifdef HAVE_ADS
- /* a full ads_connect() is actually overkill, as we don't srictly need
- to do the SASL auth in order to get the info we need, but libads
- doesn't offer a better way right now */
- ads_connect(ads);
-#endif
-
- if (!ads->config.realm) {
- return False;
- }
-
- fstrcpy(srv_name, ads->config.ldap_server_name);
- strupper(srv_name);
- *dc_ip = ads->ldap_ip;
- ads_destroy(&ads);
-
- DEBUG(4,("cm_ads_find_dc: using server='%s' IP=%s\n",
- srv_name, inet_ntoa(*dc_ip)));
-
- return True;
-}
-
-/*
- find the DC for a domain using methods appropriate for a RPC domain
-*/
-static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
-{
- struct in_addr *ip_list = NULL;
- int count, i;
-
- /* Lookup domain controller name. Try the real PDC first to avoid
- SAM sync delays */
- if (!get_dc_list(True, domain, &ip_list, &count)) {
- if (!get_dc_list(False, domain, &ip_list, &count)) {
- DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
- return False;
- }
- }
-
- /* Pick a nice close server */
- /* Look for DC on local net */
- for (i = 0; i < count; i++) {
- 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];
- SAFE_FREE(ip_list);
- return True;
- }
- 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];
- SAFE_FREE(ip_list);
- return True;
- }
- zero_ip(&ip_list[i]); /* Tried and failed. */
-
- /* Finally return first DC that we can contact using a node
- status */
- 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];
- SAFE_FREE(ip_list);
- return True;
- }
- }
-
- SAFE_FREE(ip_list);
-
- return False;
-}
-
-
static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
{
static struct get_dc_name_cache *get_dc_name_cache;
struct get_dc_name_cache *dcc;
- struct in_addr dc_ip;
- BOOL ret;
+ struct in_addr *ip_list, dc_ip;
+ int count, i;
/* Check the cache for previous lookups */
@@ -254,22 +144,66 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
DLIST_ADD(get_dc_name_cache, dcc);
- zero_ip(&dc_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 (!get_dc_list(False, domain, &ip_list, &count)) {
+ DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
+ return False;
+ }
+ }
- ret = False;
- if (lp_security() == SEC_ADS) {
- ret = cm_ads_find_dc(domain, &dc_ip, srv_name);
+ /* Pick a nice close server */
+ /* Look for DC on local net */
+
+ for (i = 0; i < count; i++) {
+ 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]);
}
- if (!ret) {
- /* fall back on rpc methods if the ADS methods fail */
- ret = cm_rpc_find_dc(domain, &dc_ip, srv_name);
+
+ /*
+ * 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. */
- if (!ret) {
- return False;
+ /* 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;
+ }
}
+ /* 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. */
+
/* We have a name so make the cache entry positive now */
+
fstrcpy(dcc->srv_name, srv_name);
DEBUG(3, ("cm_get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
@@ -277,6 +211,8 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
*ip_out = dc_ip;
+ SAFE_FREE(ip_list);
+
return True;
}
@@ -326,23 +262,11 @@ 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)
-{
+static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn, NTSTATUS result) {
struct failed_connection_cache *fcc;
SMB_ASSERT(!NT_STATUS_IS_OK(result));
- /* Check we already aren't in the cache */
-
- 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;
- }
- }
-
/* Create negative lookup cache entry for this domain and controller */
if (!(fcc = (struct failed_connection_cache *)
@@ -870,7 +794,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
return result;
}
- result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ 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)) {
@@ -884,7 +808,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
}
/* Try again */
- result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
}
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c
index abb6b9da75..20563ba7bd 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -196,9 +196,6 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
gid_t gid;
int gr_mem_len;
- /* Ensure null termination */
- state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
-
DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
state->request.data.groupname));
@@ -786,9 +783,6 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
int i;
TALLOC_CTX *mem_ctx;
- /* Ensure null termination */
- state->request.data.username[sizeof(state->request.data.username)-1]='\0';
-
DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
state->request.data.username));
diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h
index 9eea94e7c0..0f0e40a2ec 100644
--- a/source3/nsswitch/winbindd_nss.h
+++ b/source3/nsswitch/winbindd_nss.h
@@ -36,7 +36,7 @@
/* Update this when you change the interface. */
-#define WINBIND_INTERFACE_VERSION 5
+#define WINBIND_INTERFACE_VERSION 4
/* Socket commands */
@@ -107,12 +107,6 @@ enum winbindd_cmd {
WINBINDD_NUM_CMDS
};
-#define WINBIND_PAM_INFO3_NDR 0x0001
-#define WINBIND_PAM_INFO3_TEXT 0x0002
-#define WINBIND_PAM_NTKEY 0x0004
-#define WINBIND_PAM_LMKEY 0x0008
-#define WINBIND_PAM_CONTACT_TRUSTDOM 0x0010
-
/* Winbind request structure */
struct winbindd_request {
@@ -138,8 +132,6 @@ struct winbindd_request {
uint16 lm_resp_len;
fstring nt_resp;
uint16 nt_resp_len;
- fstring workstation;
- uint32 flags;
} auth_crap;
struct {
fstring user;
@@ -224,8 +216,6 @@ struct winbindd_response {
fstring nt_status_string;
fstring error_string;
int pam_error;
- char nt_session_key[16];
- char first_8_lm_hash[8];
} auth;
} data;
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index a8b508a49c..e608f826c9 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -23,41 +23,17 @@
*/
#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 = memdup(prs_data_p(&ps), size);
- if (!state->response.extra_data) {
- prs_mem_free(&ps);
- return NT_STATUS_NO_MEMORY;
- }
- state->response.length += size;
- prs_mem_free(&ps);
- return NT_STATUS_OK;
-}
-
/* 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 smb_uid_low;
@@ -70,12 +46,6 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
extern pstring global_myname;
- /* 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';
-
DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
state->request.data.auth.user));
@@ -94,14 +64,16 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
goto done;
}
+ passlen = strlen(state->request.data.auth.pass);
+
{
unsigned char local_lm_response[24];
unsigned char local_nt_response[24];
generate_random_buffer(chal, 8, False);
- SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
+ SMBencrypt( (const uchar *)state->request.data.auth.pass, chal, local_lm_response);
- SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
+ SMBNTencrypt((const uchar *)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));
@@ -168,67 +140,34 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
TALLOC_CTX *mem_ctx = NULL;
- char *user = NULL;
- char *domain = NULL;
- char *contact_domain;
- char *workstation;
+ const char *domain = NULL;
DATA_BLOB lm_resp, nt_resp;
extern pstring global_myname;
- /* Ensure null termination */
- state->request.data.auth_crap.user[sizeof(state->request.data.auth_crap.user)-1]='\0';
-
- /* Ensure null termination */
- 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_named("winbind pam auth crap for (utf8) %s", state->request.data.auth.user))) {
+ if (!(mem_ctx = talloc_init_named("winbind pam auth crap for %s", state->request.data.auth.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, &user, state->request.data.auth_crap.user) < 0) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- }
-
if (*state->request.data.auth_crap.domain) {
- if (pull_utf8_talloc(mem_ctx, &domain, state->request.data.auth_crap.domain) < 0) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- }
+ domain = talloc_strdup(mem_ctx, state->request.data.auth_crap.domain);
} else if (lp_winbind_use_default_domain()) {
- domain = lp_workgroup();
+ domain = talloc_strdup(mem_ctx, lp_workgroup());
} else {
- DEBUG(5,("no domain specified with username (%s) - failing auth\n",
- user));
+ DEBUG(5,("no domain specified with username (%s) - failing auth\n", state->request.data.auth.user));
result = NT_STATUS_INVALID_PARAMETER;
goto done;
}
- DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
- domain, user));
-
- if (lp_allow_trusted_domains() && (state->request.data.auth_crap.flags & WINBIND_PAM_CONTACT_TRUSTDOM)) {
- contact_domain = domain;
- } else {
- contact_domain = lp_workgroup();
- }
-
- if (*state->request.data.auth_crap.workstation) {
- if (pull_utf8_talloc(mem_ctx, &workstation, state->request.data.auth_crap.workstation) < 0) {
- DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
- }
- } 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;
}
@@ -236,15 +175,13 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
/*
- * Get the machine account password for the domain to contact.
- * This is either our own domain for a workstation, or possibly
- * any domain for a PDC with trusted domains.
+ * Get the machine account password for our primary domain
*/
- if (!secrets_fetch_trust_account_password (
- contact_domain, trust_passwd, &last_change_time)) {
+ 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", contact_domain));
+ "password for domain %s\n", lp_workgroup()));
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
goto done;
}
@@ -252,7 +189,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
ZERO_STRUCT(info3);
/* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(contact_domain, trust_passwd, &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 (error: %s)\n", nt_errstr(result)));
@@ -260,43 +197,27 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
}
result = cli_netlogon_sam_network_logon(cli, mem_ctx,
- user, domain,
- workstation, state->request.data.auth_crap.chal,
+ state->request.data.auth_crap.user, domain,
+ global_myname, state->request.data.auth_crap.chal,
lm_resp, nt_resp,
&info3);
if (NT_STATUS_IS_OK(result)) {
uni_group_cache_store_netlogon(mem_ctx, &info3);
- if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
- result = append_info3_as_ndr(mem_ctx, state, &info3);
- }
-
-#if 0
- /* we don't currently do this stuff right */
- if (state->request.data.auth_crap.flags & WINBIND_PAM_NTKEY) {
- SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) == sizeof(info3.user_sess_key));
- memcpy(state->response.data.auth.nt_session_key, info3.user_sess_key, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
- }
- if (state->request.data.auth_crap.flags & WINBIND_PAM_LMKEY) {
- SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) <= sizeof(info3.user_sess_key));
- memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
- }
-#endif
}
done:
state->response.data.auth.nt_status = NT_STATUS_V(result);
- push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result));
- push_utf8_fstring(state->response.data.auth.error_string, nt_errstr(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 authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n",
- domain,
- user,
- state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("NTLM CRAP authenticaion 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);
diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h
new file mode 100644
index 0000000000..ef44fb655e
--- /dev/null
+++ b/source3/nsswitch/winbindd_proto.h
@@ -0,0 +1,142 @@
+#ifndef _WINBINDD_PROTO_H_
+#define _WINBINDD_PROTO_H_
+
+/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+
+/* The following definitions come from nsswitch/winbindd.c */
+
+void winbind_process_packet(struct winbindd_cli_state *state);
+void winbind_client_read(struct winbindd_cli_state *state);
+int winbind_setup_common(void);
+
+/* The following definitions come from nsswitch/winbindd_ads.c */
+
+ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope,
+ const char *exp,
+ const char **attrs, void **res);
+ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
+ const char *exp,
+ const char **attrs);
+ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res,
+ const char *dn,
+ const char **attrs);
+
+/* The following definitions come from nsswitch/winbindd_cache.c */
+
+void wcache_flush_cache(void);
+void winbindd_check_cache_size(time_t t);
+struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status);
+
+/* The following definitions come from nsswitch/winbindd_cm.c */
+
+CLI_POLICY_HND *cm_get_lsa_handle(char *domain);
+CLI_POLICY_HND *cm_get_sam_handle(char *domain);
+CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid);
+CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid,
+ uint32 user_rid);
+CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
+ uint32 group_rid);
+NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
+ struct cli_state **cli);
+void winbindd_cm_status(void);
+
+/* The following definitions come from nsswitch/winbindd_dual.c */
+
+int dual_select_setup(fd_set *fds, int maxfd);
+void dual_select(fd_set *fds);
+void dual_send_request(struct winbindd_cli_state *state);
+void do_dual_daemon(void);
+
+/* The following definitions come from nsswitch/winbindd_group.c */
+
+enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state);
+
+/* The following definitions come from nsswitch/winbindd_idmap.c */
+
+BOOL winbindd_idmap_get_uid_from_sid(DOM_SID *sid, uid_t *uid);
+BOOL winbindd_idmap_get_gid_from_sid(DOM_SID *sid, gid_t *gid);
+BOOL winbindd_idmap_get_uid_from_rid(const char *dom_name, uint32 rid, uid_t *uid);
+BOOL winbindd_idmap_get_gid_from_rid(const char *dom_name, uint32 rid, gid_t *gid);
+BOOL get_sid_from_id(int id, DOM_SID *sid, BOOL isgroup);
+BOOL winbindd_idmap_get_sid_from_uid(uid_t uid, DOM_SID *sid);
+BOOL winbindd_idmap_get_sid_from_gid(gid_t gid, DOM_SID *sid);
+BOOL winbindd_idmap_get_rid_from_uid(uid_t uid, uint32 *user_rid,
+ struct winbindd_domain **domain);
+BOOL winbindd_idmap_get_rid_from_gid(gid_t gid, uint32 *group_rid,
+ struct winbindd_domain **domain);
+BOOL winbindd_idmap_init(void);
+BOOL winbindd_idmap_close(void);
+void winbindd_idmap_status(void);
+
+/* The following definitions come from nsswitch/winbindd_misc.c */
+
+enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
+ *state);
+enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_ping(struct winbindd_cli_state
+ *state);
+enum winbindd_result winbindd_info(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_domain_name(struct winbindd_cli_state *state);
+
+/* The following definitions come from nsswitch/winbindd_pam.c */
+
+enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) ;
+enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) ;
+enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state);
+
+/* The following definitions come from nsswitch/winbindd_rpc.c */
+
+
+/* The following definitions come from nsswitch/winbindd_sid.c */
+
+enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state);
+
+/* The following definitions come from nsswitch/winbindd_user.c */
+
+enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) ;
+enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state);
+
+/* The following definitions come from nsswitch/winbindd_util.c */
+
+struct winbindd_domain *domain_list(void);
+void free_domain_list(void);
+BOOL init_domain_list(void);
+struct winbindd_domain *find_domain_from_name(const char *domain_name);
+struct winbindd_domain *find_domain_from_sid(DOM_SID *sid);
+BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
+ const char *name, DOM_SID *sid,
+ enum SID_NAME_USE *type);
+BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
+ fstring dom_name,
+ fstring name,
+ enum SID_NAME_USE *type);
+void free_getent_state(struct getent_state *state);
+BOOL winbindd_param_init(void);
+BOOL check_domain_env(char *domain_env, char *domain);
+BOOL parse_domain_user(const char *domuser, fstring domain, fstring user);
+void fill_domain_username(fstring name, const char *domain, const char *user);
+
+/* The following definitions come from nsswitch/winbindd_wins.c */
+
+enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state);
+
+#endif /* _WINBINDD_PROTO_H_ */
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c
index 5ec34f663d..2bb0e8c49f 100644
--- a/source3/nsswitch/winbindd_rpc.c
+++ b/source3/nsswitch/winbindd_rpc.c
@@ -575,23 +575,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)
{
CLI_POLICY_HND *hnd;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 enum_ctx = 0;
+ uint32 pref_num_domains = 5;
DEBUG(3,("rpc: trusted_domains\n"));
*num_domains = 0;
- *alt_names = NULL;
if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
goto done;
result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
- &hnd->pol, &enum_ctx,
+ &hnd->pol, &enum_ctx, &pref_num_domains,
num_domains, names, dom_sids);
done:
return result;
@@ -622,13 +621,6 @@ done:
return status;
}
-/* 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,
@@ -641,6 +633,5 @@ struct winbindd_methods msrpc_methods = {
lookup_groupmem,
sequence_number,
trusted_domains,
- domain_sid,
- alternate_name
+ domain_sid
};
diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c
index 44f857d6be..372898a08a 100644
--- a/source3/nsswitch/winbindd_sid.c
+++ b/source3/nsswitch/winbindd_sid.c
@@ -36,9 +36,6 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
fstring name;
fstring dom_name;
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid,
state->request.data.sid));
@@ -82,12 +79,6 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
DOM_SID sid;
struct winbindd_domain *domain;
- /* 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';
-
DEBUG(3, ("[%5d]: lookupname %s%s%s\n", state->pid,
state->request.data.name.dom_name,
lp_winbind_separator(),
@@ -121,9 +112,6 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
DEBUG(3, ("[%5d]: sid to uid %s\n", state->pid,
state->request.data.sid));
@@ -151,9 +139,6 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- /* Ensure null termination */
- state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
-
DEBUG(3, ("[%5d]: sid to gid %s\n", state->pid,
state->request.data.sid));
diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c
index 4f57fd2c72..55593d6ae5 100644
--- a/source3/nsswitch/winbindd_user.c
+++ b/source3/nsswitch/winbindd_user.c
@@ -103,9 +103,6 @@ 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, ("[%5d]: getpwnam %s\n", state->pid,
state->request.data.username));
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index daa3abb340..d5668a2bb6 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -74,17 +74,19 @@ void free_domain_list(void)
}
/* 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;
/* 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 (strcmp(domain_name, domain->name) == 0 ||
- strcmp(domain_name, domain->alt_name) == 0) {
+ if (strcmp(domain_name, domain->name) == 0) {
+ DEBUG(3, ("domain %s already in domain list\n",
+ domain_name));
return domain;
}
}
@@ -99,95 +101,40 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
ZERO_STRUCTP(domain);
- /* prioritise the short name */
- if (strchr_m(domain_name, '.') && alt_name && *alt_name) {
- fstrcpy(domain->name, alt_name);
- fstrcpy(domain->alt_name, domain_name);
- } else {
fstrcpy(domain->name, domain_name);
- if (alt_name) {
- fstrcpy(domain->alt_name, alt_name);
- }
- }
-
domain->methods = methods;
domain->sequence_number = DOM_SEQUENCE_NONE;
domain->last_seq_check = 0;
- if (sid) {
- sid_copy(&domain->sid, sid);
- }
/* Link to domain list */
- DLIST_ADD(_domain_list, domain);
- DEBUG(1,("Added domain %s %s %s\n",
- domain->name, domain->alt_name,
- sid?sid_string_static(&domain->sid):""));
+ DLIST_ADD(_domain_list, domain);
return domain;
}
-
-/*
- rescan our domains looking for new trusted domains
- */
-void rescan_trusted_domains(void)
-{
- struct winbindd_domain *domain;
- TALLOC_CTX *mem_ctx;
- static time_t last_scan;
- time_t t = time(NULL);
-
- /* ony rescan every few minutes */
- if ((unsigned)(t - last_scan) < WINBINDD_RESCAN_FREQ) {
- return;
- }
- last_scan = time(NULL);
-
- DEBUG(1, ("scanning trusted domain list\n"));
-
- if (!(mem_ctx = talloc_init_named("init_domain_list")))
- return;
-
- for (domain = _domain_list; domain; domain = domain->next) {
- NTSTATUS result;
- char **names;
- char **alt_names;
- int num_domains = 0;
- DOM_SID *dom_sids;
- int i;
-
- result = domain->methods->trusted_domains(domain, mem_ctx, &num_domains,
- &names, &alt_names, &dom_sids);
- if (!NT_STATUS_IS_OK(result)) {
- continue;
- }
-
- /* Add each domain to the trusted domain list. Each domain inherits
- the access methods of its parent */
- 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]);
- }
- }
-
- talloc_destroy(mem_ctx);
-}
-
/* Look up global info for the winbind daemon */
+
BOOL init_domain_list(void)
{
NTSTATUS result;
+ TALLOC_CTX *mem_ctx;
extern struct winbindd_methods cache_methods;
struct winbindd_domain *domain;
+ DOM_SID *dom_sids;
+ char **names;
+ int num_domains = 0;
+
+ if (!(mem_ctx = talloc_init_named("init_domain_list")))
+ return False;
/* Free existing list */
+
free_domain_list();
/* Add ourselves as the first entry */
- domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL);
+
+ domain = add_trusted_domain(lp_workgroup(), &cache_methods);
/* Now we *must* get the domain sid for our primary domain. Go into
a holding pattern until that is available */
@@ -200,12 +147,29 @@ BOOL init_domain_list(void)
result = cache_methods.domain_sid(domain, &domain->sid);
}
- /* get any alternate name for the primary domain */
- cache_methods.alternate_name(domain);
+ DEBUG(1,("Added domain %s (%s)\n",
+ domain->name,
+ sid_string_static(&domain->sid)));
+
+ DEBUG(1, ("getting trusted domain list\n"));
- /* do an initial scan for trusted domains */
- rescan_trusted_domains();
+ result = cache_methods.trusted_domains(domain, mem_ctx, &num_domains,
+ &names, &dom_sids);
+ /* 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)));
+ }
+ }
+
+ talloc_destroy(mem_ctx);
return True;
}
@@ -220,7 +184,7 @@ 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;
}
diff --git a/source3/nsswitch/winbindd_wins.c b/source3/nsswitch/winbindd_wins.c
index 8ddd5dc10d..8f9a7414bd 100644
--- a/source3/nsswitch/winbindd_wins.c
+++ b/source3/nsswitch/winbindd_wins.c
@@ -122,9 +122,6 @@ 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, ("[%5d]: wins_byip %s\n", state->pid,
state->request.data.winsreq));
@@ -169,9 +166,6 @@ 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, ("[%5d]: wins_byname %s\n", state->pid,
state->request.data.winsreq));
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index b16f4483f8..6e3ce460cd 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -87,7 +87,6 @@ static BOOL defaults_saved = False;
*/
typedef struct
{
- char *smb_ports;
char *dos_charset;
char *unix_charset;
char *display_charset;
@@ -166,7 +165,6 @@ typedef struct
char *szGuestaccount;
char *szManglingMethod;
int max_log_size;
- char *szLogLevel;
int mangled_stack;
int max_xmit;
int max_mux;
@@ -258,9 +256,7 @@ typedef struct
BOOL bHostnameLookups;
BOOL bUseSpnego;
BOOL bUnixExtensions;
- BOOL bDisableNetbios;
int restrict_anonymous;
- int name_cache_timeout;
}
global;
@@ -317,7 +313,6 @@ typedef struct
char *fstype;
char *szVfsObjectFile;
char *szVfsOptions;
- char *szVfsPath;
int iMinPrintSpace;
int iMaxPrintJobs;
int iWriteCacheSize;
@@ -344,7 +339,6 @@ typedef struct
BOOL bCaseMangle;
BOOL bHideDotFiles;
BOOL bHideUnReadable;
- BOOL bHideUnWriteableFiles;
BOOL bBrowseable;
BOOL bAvailable;
BOOL bRead_only;
@@ -437,7 +431,6 @@ static service sDefault = {
NULL, /* fstype */
NULL, /* vfs object */
NULL, /* vfs options */
- NULL, /* vfs path */
0, /* iMinPrintSpace */
1000, /* iMaxPrintJobs */
0, /* iWriteCacheSize */
@@ -464,7 +457,6 @@ static service sDefault = {
False, /* case mangle */
True, /* bHideDotFiles */
False, /* bHideUnReadable */
- False, /* bHideUnWriteableFiles */
True, /* bBrowseable */
True, /* bAvailable */
True, /* bRead_only */
@@ -553,9 +545,7 @@ static struct enum_list enum_security[] = {
{SEC_USER, "USER"},
{SEC_SERVER, "SERVER"},
{SEC_DOMAIN, "DOMAIN"},
-#ifdef HAVE_ADS
{SEC_ADS, "ADS"},
-#endif
{-1, NULL}
};
@@ -769,8 +759,8 @@ static struct parm_struct parm_table[] = {
{"Logging Options", P_SEP, P_SEPARATOR},
{"admin log", P_BOOL, P_GLOBAL, &Globals.bAdminLog, NULL, NULL, 0},
- {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, 0},
- {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, 0},
+ {"log level", P_STRING, P_GLOBAL, NULL, handle_debug_list, NULL, 0},
+ {"debuglevel", P_STRING, P_GLOBAL, NULL, 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},
@@ -784,7 +774,6 @@ static struct parm_struct parm_table[] = {
{"Protocol Options", P_SEP, P_SEPARATOR},
- {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, 0},
{"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},
@@ -793,7 +782,6 @@ static struct parm_struct parm_table[] = {
{"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},
- {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, 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 },
@@ -839,8 +827,6 @@ static struct parm_struct parm_table[] = {
{"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, 0},
{"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
- {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, 0},
-
{"Printing Options", P_SEP, P_SEPARATOR},
{"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT},
@@ -889,7 +875,6 @@ static struct parm_struct parm_table[] = {
{"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},
- {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, 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 },
{"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
@@ -1036,7 +1021,6 @@ static struct parm_struct parm_table[] = {
{"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},
- {"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE},
{"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
@@ -1073,26 +1057,26 @@ static void init_printer_values(void)
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:
@@ -1108,19 +1092,19 @@ static void init_printer_values(void)
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;
@@ -1207,7 +1191,7 @@ static void init_globals(void)
string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
- Globals.szPassdbBackend = str_list_make("smbpasswd unixsam", NULL);
+ Globals.szPassdbBackend = str_list_make("smbpasswd unixsam");
/* use the new 'hash2' method by default */
string_set(&Globals.szManglingMethod, "hash2");
@@ -1217,9 +1201,6 @@ static void init_globals(void)
/* using UTF8 by default allows us to support all chars */
string_set(&Globals.unix_charset, "UTF8");
- /* Use codepage 850 as a default for the dos character set */
- string_set(&Globals.dos_charset, "CP850");
-
/*
* Allow the default PASSWD_CHAT to be overridden in local.h.
*/
@@ -1281,7 +1262,6 @@ static void init_globals(void)
Globals.bSyslogOnly = False;
Globals.bAdminLog = False;
Globals.bTimestampLogs = True;
- string_set(&Globals.szLogLevel, "0");
Globals.bDebugHiresTimestamp = False;
Globals.bDebugPid = False;
Globals.bDebugUid = False;
@@ -1378,11 +1358,8 @@ static void init_globals(void)
Globals.bWinbindEnumGroups = True;
Globals.bWinbindUseDefaultDomain = False;
- Globals.name_cache_timeout = 660; /* In seconds */
-
Globals.bUseSpnego = True;
- string_set(&Globals.smb_ports, SMB_PORTS);
}
static TALLOC_CTX *lp_talloc;
@@ -1430,10 +1407,7 @@ static char *lp_string(const char *s)
else
StrnCpy(ret, s, len);
- if (trim_string(ret, "\"", "\"")) {
- if (strchr(ret,'"') != NULL)
- StrnCpy(ret, s, len);
- }
+ trim_string(ret, "\"", "\"");
standard_sub_basic(current_user_info.smb_name,ret,len+100);
return (ret);
@@ -1471,7 +1445,6 @@ 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_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)
@@ -1525,7 +1498,7 @@ 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_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)
@@ -1554,7 +1527,6 @@ 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_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)
@@ -1670,7 +1642,6 @@ FN_LOCAL_LIST(lp_printer_admin, printer_admin)
FN_LOCAL_STRING(lp_fstype, fstype)
FN_LOCAL_STRING(lp_vfsobj, szVfsObjectFile)
FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
-FN_LOCAL_STRING(lp_vfs_path, szVfsPath)
static FN_LOCAL_STRING(lp_volume, volume)
FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
@@ -1687,7 +1658,6 @@ FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
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)
@@ -1745,7 +1715,6 @@ FN_LOCAL_CHAR(lp_magicchar, magic_char)
FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
FN_GLOBAL_BOOL(lp_algorithmic_rid_base, &Globals.bAlgorithmicRidBase)
-FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
typedef struct _param_opt_struct param_opt_struct;
struct _param_opt_struct {
@@ -1935,8 +1904,8 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService,
if (i < 0)
return (False);
- if (!(*(ServicePtrs[iDefaultService]->szPath))
- || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
+ if (!(*(ServicePtrs[i]->szPath))
+ || strequal(ServicePtrs[i]->szPath, lp_pathname(-1))) {
pstrcpy(newHomedir, pszHomedir);
} else {
pstrcpy(newHomedir, lp_pathname(iDefaultService));
@@ -1956,7 +1925,7 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService,
ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
DEBUG(3,
- ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
+ ("adding home's share [%s] for user %s at %s\n", pszHomename,
user, newHomedir));
return (True);
@@ -2002,12 +1971,14 @@ static BOOL lp_add_ipc(char *ipc_name, BOOL guest_ok)
return (True);
}
+BOOL (*register_printer_fn)(const char *);
+
/***************************************************************************
add a new printer service, with defaults coming from service iFrom.
***************************************************************************/
-BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
+BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
{
- const char *comment = "From Printcap";
+ char *comment = "From Printcap";
int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
if (i < 0)
@@ -2034,6 +2005,8 @@ BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
DEBUG(3, ("adding printer service %s\n", pszPrintername));
update_server_announce_as_printserver();
+ if (register_printer_fn && (!(*register_printer_fn)(pszPrintername)))
+ return False;
return (True);
}
@@ -2650,7 +2623,6 @@ static BOOL handle_debug_list( char *pszParmValueIn, char **ptr )
pstring pszParmValue;
pstrcpy(pszParmValue, pszParmValueIn);
- string_set(ptr, pszParmValueIn);
return debug_parse_levels( pszParmValue );
}
@@ -2872,7 +2844,7 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
break;
case P_LIST:
- *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
+ *(char ***)parm_ptr = str_list_make(pszParmValue);
break;
case P_STRING:
@@ -3513,8 +3485,8 @@ static void set_server_role(void)
case SEC_DOMAIN:
case SEC_ADS:
if (lp_domain_logons()) {
- server_role = ROLE_DOMAIN_PDC;
- DEBUG(10,("set_server_role:ROLE_DOMAIN_PDC\n"));
+ server_role = ROLE_DOMAIN_BDC;
+ DEBUG(10,("set_server_role:ROLE_DOMAIN_BDC\n"));
break;
}
server_role = ROLE_DOMAIN_MEMBER;
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index a9c6f0729b..4e3d558e98 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -157,12 +157,6 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
{
GROUP_MAP map;
- const char *guest_account = lp_guestaccount();
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("NULL guest account!?!?\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
if (!pwd) {
return NT_STATUS_UNSUCCESSFUL;
}
@@ -189,35 +183,23 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
-- abartlet 11-May-02
*/
+ if (!pdb_set_user_sid_from_rid(sam_account,
+ fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
+ DEBUG(0,("Can't set User SID from RID!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- /* Ensure this *must* be set right */
- if (strcmp(pwd->pw_name, guest_account) == 0) {
- if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else {
-
- if (!pdb_set_user_sid_from_rid(sam_account,
- fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
- DEBUG(0,("Can't set User SID from RID!\n"));
+ /* call the mapping code here */
+ if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
+ if (!pdb_set_group_sid(sam_account,&map.sid)){
+ DEBUG(0,("Can't set Group SID!\n"));
return NT_STATUS_INVALID_PARAMETER;
}
-
- /* call the mapping code here */
- if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
- if (!pdb_set_group_sid(sam_account,&map.sid)){
- DEBUG(0,("Can't set Group SID!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- }
- else {
- if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
- DEBUG(0,("Can't set Group SID\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
+ }
+ else {
+ if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
+ DEBUG(0,("Can't set Group SID\n"));
+ return NT_STATUS_INVALID_PARAMETER;
}
}
@@ -546,9 +528,6 @@ BOOL pdb_rid_is_user(uint32 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
@@ -592,6 +571,14 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
fstrcpy(name, "Administrator");
}
return True;
+
+ } else if (rid == DOMAIN_USER_RID_GUEST) {
+ char *p = lp_guestaccount();
+ *psid_name_use = SID_NAME_USER;
+ if(!next_token(&p, name, NULL, sizeof(fstring)))
+ fstrcpy(name, "Guest");
+ return True;
+
}
/*
@@ -607,7 +594,6 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
}
/* This now does the 'generic' mapping in pdb_unix */
- /* 'guest' is also handled there */
if (pdb_getsampwsid(sam_account, sid)) {
fstrcpy(name, pdb_get_username(sam_account));
*psid_name_use = SID_NAME_USER;
@@ -730,9 +716,15 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
/* check if it's a mapped group */
if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
- /* yes it's a mapped group */
- sid_copy(&local_sid, &map.sid);
- *psid_name_use = map.sid_name_use;
+ if (map.gid!=-1) {
+ /* yes it's a mapped group to a valid unix group */
+ sid_copy(&local_sid, &map.sid);
+ *psid_name_use = map.sid_name_use;
+ }
+ else {
+ /* it's a correct name but not mapped so it points to nothing*/
+ return False;
+ }
} else {
/* it's not a mapped group */
grp = getgrnam(user);
@@ -785,8 +777,6 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
if (pdb_getsampwnam(sam_user, pass->pw_name)) {
sid_copy(psid, pdb_get_user_sid(sam_user));
- } else if (strcmp(pass->pw_name, lp_guestaccount()) == 0) {
- sid_append_rid(psid, DOMAIN_USER_RID_GUEST);
} else {
sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid));
}
@@ -812,13 +802,25 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
Convert a SID to uid - locally.
****************************************************************************/
-BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
+BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
{
+ DOM_SID dom_sid;
+ uint32 rid;
fstring str;
SAM_ACCOUNT *sam_user = NULL;
*name_type = SID_NAME_UNKNOWN;
+ sid_copy(&dom_sid, psid);
+ sid_split_rid(&dom_sid, &rid);
+
+ /*
+ * We can only convert to a uid if this is our local
+ * Domain SID (ie. we are the controling authority).
+ */
+ if (!sid_equal(get_global_sam_sid(), &dom_sid))
+ return False;
+
if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
return False;
@@ -830,37 +832,12 @@ BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_
}
DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
(unsigned int)*puid, pdb_get_username(sam_user)));
- pdb_free_sam(&sam_user);
} else {
-
- DOM_SID dom_sid;
- uint32 rid;
- GROUP_MAP map;
-
- pdb_free_sam(&sam_user);
-
- if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
- DEBUG(3, ("local_sid_to_uid: SID '%s' is a group, not a user... \n", sid_to_string(str, psid)));
- /* It's a group, not a user... */
- return False;
- }
-
- sid_copy(&dom_sid, psid);
- if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
- DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid)));
- return False;
- }
-
- if (!pdb_rid_is_user(rid)) {
- DEBUG(3, ("local_sid_to_uid: sid '%s' cannot be mapped to a uid algorithmicly becouse it is a group\n", sid_to_string(str, psid)));
- return False;
- }
-
- *puid = fallback_pdb_user_rid_to_uid(rid);
-
- DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n",
- sid_to_string(str, psid), (signed long int)(*puid)));
+ DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID was not found in passdb.\n", sid_to_string( str, psid)));
+ pdb_free_sam(&sam_user);
+ return False;
}
+ pdb_free_sam(&sam_user);
*name_type = SID_NAME_USER;
@@ -891,13 +868,18 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
Convert a SID to gid - locally.
****************************************************************************/
-BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
+BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
{
+ DOM_SID dom_sid;
+ uint32 rid;
fstring str;
GROUP_MAP map;
*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).
@@ -905,45 +887,35 @@ BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_
* Or in the Builtin SID too. JFM, 11/30/2001
*/
+ if (!sid_equal(get_global_sam_sid(), &dom_sid))
+ return False;
+
if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
/* the SID is in the mapping table but not mapped */
if (map.gid==-1)
return False;
+ if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)){
+ DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n",
+ sid_string_static(&map.sid)));
+ return False;
+ }
*pgid = map.gid;
*name_type = map.sid_name_use;
- DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n",
- sid_to_string( str, psid),
+ DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", sid_to_string( str, psid),
map.nt_name, (unsigned int)*pgid));
} else {
- uint32 rid;
- SAM_ACCOUNT *sam_user = NULL;
- if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
- return False;
-
- if (pdb_getsampwsid(sam_user, psid)) {
- return False;
- pdb_free_sam(&sam_user);
- }
-
- pdb_free_sam(&sam_user);
-
- if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
- DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid)));
- return False;
- }
-
if (pdb_rid_is_user(rid))
return False;
-
+
*pgid = pdb_group_rid_to_gid(rid);
*name_type = SID_NAME_ALIAS;
DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u).\n", sid_to_string( str, psid),
(unsigned int)*pgid));
}
-
+
return True;
}
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index 2da6de7270..dff4b40f4d 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -250,7 +250,7 @@ const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
return (NULL);
}
-const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass)
+const char* pdb_get_dirdrive (const SAM_ACCOUNT *sampass)
{
if (sampass)
return (sampass->private.dir_drive);
@@ -1028,14 +1028,15 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
if (!pdb_set_pass_last_set_time (sampass, time(NULL)))
return False;
- if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
- || (expire==(uint32)-1)) {
+ account_policy_get(AP_MAX_PASSWORD_AGE, &expire);
+
+ if (expire==(uint32)-1) {
if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), False))
return False;
} else {
if (!pdb_set_pass_must_change_time (sampass,
- pdb_get_pass_last_set_time(sampass)
- + expire, True))
+ pdb_get_pass_last_set_time(sampass)
+ + expire, True))
return False;
}
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index f311223d77..3b0f54b2b3 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -123,7 +123,7 @@ static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_ac
return False;
}
-static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
+static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, DOM_SID *sid)
{
struct pdb_methods *curmethods;
if ((!context)) {
@@ -353,7 +353,7 @@ NTSTATUS make_pdb_context_list(struct pdb_context **context, char **selected)
NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected)
{
NTSTATUS ret;
- char **newsel = str_list_make(selected, NULL);
+ char **newsel = str_list_make(selected);
ret = make_pdb_context_list(context, newsel);
str_list_free(&newsel);
return ret;
@@ -434,7 +434,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username);
}
-BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
+BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, DOM_SID *sid)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index f82cb4488f..24eb7b9dc1 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -1,12 +1,11 @@
/*
Unix SMB/CIFS implementation.
LDAP protocol helper functions for SAMBA
- Copyright (C) Jean François Micouleau 1998
- Copyright (C) Gerald Carter 2001
- Copyright (C) Shahms King 2001
- Copyright (C) Andrew Bartlett 2002
- Copyright (C) Stefan (metze) Metzmacher 2002
-
+ Copyright (C) Gerald Carter 2001
+ Copyright (C) Shahms King 2001
+ Copyright (C) Jean François Micouleau 1998
+ 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
@@ -71,14 +70,8 @@ struct ldapsam_privates {
uint32 low_nua_rid;
uint32 high_nua_rid;
-
- char *bind_dn;
- char *bind_secret;
};
-
-static struct ldapsam_privates *static_ldap_state;
-
static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
/*******************************************************************
@@ -160,13 +153,11 @@ static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
{
- int version;
-
if (geteuid() != 0) {
DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n"));
return False;
}
-
+
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
@@ -174,16 +165,6 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
DEBUG(0, ("ldap_initialize: %s\n", strerror(errno)));
return (False);
}
-
- 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);
- }
- }
-
#else
/* Parse the string manually */
@@ -192,6 +173,7 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
int rc;
int tls = LDAP_OPT_X_TLS_HARD;
int port = 0;
+ int version;
fstring protocol;
fstring host;
const char *p = ldap_state->uri;
@@ -270,92 +252,43 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
/*******************************************************************
- a rebind function for authenticated referrals
- This version takes a void* that we can shove useful stuff in :-)
+ Add a rebind function for authenticated referrals
******************************************************************/
-static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
- int *methodp, int freeit, void *arg)
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+ int *method, int freeit )
{
- struct ldapsam_privates *ldap_state = arg;
+ int rc;
+ char *ldap_dn;
+ char *ldap_secret;
/** @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 {
+ if (freeit != 0)
+ {
+
+ if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
+ {
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+ return LDAP_OPERATIONS_ERROR; /* No idea what to return */
+ }
+
DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
- ldap_state->bind_dn));
+ ldap_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;
+ rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+
+ SAFE_FREE(ldap_dn);
+ SAFE_FREE(ldap_secret);
+
+ return rc;
}
return 0;
}
/*******************************************************************
- a rebind function for authenticated referrals
- This version takes a void* that we can shove useful stuff in :-)
- and actually does the connection.
-******************************************************************/
-
-static int rebindproc_connect_with_state (LDAP *ldap_struct,
- LDAP_CONST char *url,
- ber_tag_t request,
- ber_int_t msgid, void *arg)
-{
- struct ldapsam_privates *ldap_state = arg;
- int rc;
- DEBUG(5,("ldap_connect_system: 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);
-
- return rc;
-}
-
-/*******************************************************************
- Add a rebind function for authenticated referrals
-******************************************************************/
-
-static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
- int *method, int freeit )
-{
- return rebindproc_with_state(ldap_struct, whop, credp,
- method, freeit, static_ldap_state);
-
-}
-
-/*******************************************************************
- a rebind function for authenticated referrals
- this also does the connection, but no void*.
-******************************************************************/
-
-static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
- ber_int_t msgid)
-{
- return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
- static_ldap_state);
-}
-
-
-/*******************************************************************
connect to the ldap server under system privilege.
******************************************************************/
static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
@@ -364,10 +297,6 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
char *ldap_dn;
char *ldap_secret;
- /* The rebind proc needs this *HACK*. We are not multithreaded, so
- this will work, but it's not nice. */
- static_ldap_state = ldap_state;
-
/* get the password */
if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
{
@@ -375,32 +304,19 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
return False;
}
- 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 as \"%s\"\n",
ldap_dn));
+
+ ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc));
-#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
-# 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
rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+ SAFE_FREE(ldap_dn);
+ SAFE_FREE(ldap_secret);
+
if (rc != LDAP_SUCCESS)
{
DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
@@ -840,20 +756,18 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
/* leave as default */
} else {
pdb_gethexpwd(temp, smblmpwd);
- memset((char *)temp, '\0', strlen(temp)+1);
+ memset((char *)temp, '\0', sizeof(temp));
if (!pdb_set_lanman_passwd(sampass, smblmpwd))
return False;
- ZERO_STRUCT(smblmpwd);
}
if (!get_single_attribute (ldap_struct, entry, "ntPassword", temp)) {
/* leave as default */
} else {
pdb_gethexpwd(temp, smbntpwd);
- memset((char *)temp, '\0', strlen(temp)+1);
+ memset((char *)temp, '\0', sizeof(temp));
if (!pdb_set_nt_passwd(sampass, smbntpwd))
return False;
- ZERO_STRUCT(smbntpwd);
}
if (!get_single_attribute (ldap_struct, entry, "acctFlags", temp)) {
@@ -966,7 +880,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
- make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass));
+ make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dirdrive(sampass));
if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT))
make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
@@ -1239,10 +1153,6 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
BOOL ret = False;
- /* The rebind proc needs this *HACK*. We are not multithreaded, so
- this will work, but it's not nice. */
- static_ldap_state = ldap_state;
-
while (!ret) {
if (!ldap_state->entry)
return False;
@@ -1293,7 +1203,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us
if (entry)
{
if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
- DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
+ DEBUG(0,("ldapsam_getsampwnam: init_sam_from_ldap failed!\n"));
ldap_msgfree(result);
ldap_unbind(ldap_struct);
return False;
@@ -1337,7 +1247,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
if (ldap_count_entries(ldap_struct, result) < 1)
{
- DEBUG(4,
+ DEBUG(0,
("We don't find this rid [%i] count=%d\n", rid,
ldap_count_entries(ldap_struct, result)));
ldap_unbind(ldap_struct);
@@ -1348,7 +1258,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
if (entry)
{
if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
- DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
+ DEBUG(0,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
ldap_msgfree(result);
ldap_unbind(ldap_struct);
return False;
@@ -1365,7 +1275,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
}
}
-static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
{
uint32 rid;
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
@@ -1620,13 +1530,6 @@ static void free_private_data(void **vp)
ldap_unbind((*ldap_state)->ldap_struct);
}
- 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);
-
*ldap_state = NULL;
/* No need to free any further, as it is talloc()ed */
diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c
index 2d37c3b8fb..9c5b2e1171 100644
--- a/source3/passdb/pdb_nisplus.c
+++ b/source3/passdb/pdb_nisplus.c
@@ -735,17 +735,17 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
/* dir_drive */
/* must support set, unset and change */
- if( (pdb_get_dir_drive(sampass) &&
+ if( (pdb_get_dirdrive(sampass) &&
!ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
(ENTRY_VAL(old, NPF_DIR_DRIVE) &&
- !pdb_get_dir_drive(sampass)) ||
+ !pdb_get_dirdrive(sampass)) ||
(ENTRY_VAL(old, NPF_DIR_DRIVE) &&
- pdb_get_dir_drive(sampass) &&
+ pdb_get_dirdrive(sampass) &&
strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
- pdb_get_dir_drive(sampass)))) {
+ pdb_get_dirdrive(sampass)))) {
need_to_modify = True;
- set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dir_drive(sampass),
- strlen(pdb_get_dir_drive(sampass)), EN_MODIFIED);
+ set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
+ strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
}
/* logon_script */
@@ -860,7 +860,7 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
set_single_attribute(obj, NPF_HOME_DIR,
homedir, strlen(homedir), 0);
- if(!(dirdrive = pdb_get_dir_drive(sampass)))
+ if(!(dirdrive = pdb_get_dirdrive(sampass)))
dirdrive = empty;
set_single_attribute(obj, NPF_DIR_DRIVE,
@@ -1032,7 +1032,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
Routine to search the nisplus passwd file for an entry matching the username
*************************************************************************/
-BOOL pdb_getsampwsid(SAM_ACCOUNT * user, const DOM_SID *sid)
+BOOL pdb_getsampwsid(SAM_ACCOUNT * user, DOM_SID *sid)
{
uint32 rid;
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c
index a5af0a786e..8c7ba364b8 100644
--- a/source3/passdb/pdb_smbpasswd.c
+++ b/source3/passdb/pdb_smbpasswd.c
@@ -1417,7 +1417,7 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s
return True;
}
-static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
{
uint32 rid;
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index 27453fc1af..6279318969 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -354,8 +354,7 @@ static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state,
* Only updates fields which have been set (not defaults from smb.conf)
*/
- if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
- dir_drive = pdb_get_dir_drive(sampass);
+ 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;
@@ -542,7 +541,7 @@ static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user
/* increment to next in line */
tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
- /* do we have an valid iteration pointer? */
+ /* do we have an valid interation pointer? */
if(tdb_state->passwd_tdb == NULL) {
DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
return False;
@@ -669,7 +668,7 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use
return tdbsam_getsampwnam (my_methods, user, name);
}
-static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
{
uint32 rid;
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
diff --git a/source3/passdb/pdb_unix.c b/source3/passdb/pdb_unix.c
index 06f12164eb..b4092b88f8 100644
--- a/source3/passdb/pdb_unix.c
+++ b/source3/passdb/pdb_unix.c
@@ -49,36 +49,23 @@ static BOOL unixsam_getsampwrid (struct pdb_methods *methods,
{
struct passwd *pass;
BOOL ret = False;
- const char *guest_account = lp_guestaccount();
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("NULL guest account!?!?\n"));
- return False;
- }
-
if (!methods) {
DEBUG(0,("invalid methods\n"));
return False;
}
-
- if (rid == DOMAIN_USER_RID_GUEST) {
- pass = getpwnam_alloc(guest_account);
- if (!pass) {
- DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account));
- return False;
- }
- } else if (pdb_rid_is_user(rid)) {
+
+ if (pdb_rid_is_user(rid)) {
pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid));
- } else {
- return False;
+
+ if (pass) {
+ ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
+ passwd_free(&pass);
+ }
}
-
- ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
- passwd_free(&pass);
-
return ret;
}
-static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
{
uint32 rid;
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index ec67b74390..3ecaf52e58 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -128,47 +128,6 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
return True;
}
-BOOL secrets_store_domain_guid(char *domain, GUID *guid)
-{
- fstring key;
-
- slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
- strupper(key);
- return secrets_store(key, guid, sizeof(GUID));
-}
-
-BOOL secrets_fetch_domain_guid(char *domain, GUID *guid)
-{
- GUID *dyn_guid;
- fstring key;
- size_t size;
- GUID new_guid;
-
- slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
- strupper(key);
- dyn_guid = (GUID *)secrets_fetch(key, &size);
-
- DEBUG(6,("key is %s, guid is at %x, size is %d\n", key, dyn_guid, size));
-
- if ((NULL == dyn_guid) && (ROLE_DOMAIN_PDC == lp_server_role())) {
- uuid_generate_random(&new_guid);
- if (!secrets_store_domain_guid(domain, &new_guid))
- return False;
- dyn_guid = (GUID *)secrets_fetch(key, &size);
- if (dyn_guid == NULL)
- return False;
- }
-
- if (size != sizeof(GUID))
- {
- SAFE_FREE(dyn_guid);
- return False;
- }
-
- *guid = *dyn_guid;
- SAFE_FREE(dyn_guid);
- return True;
-}
/**
* Form a key for fetching the machine trust account password
@@ -219,7 +178,7 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16],
if (plaintext) {
/* we have an ADS password - use that */
DEBUG(4,("Using ADS machine password\n"));
- E_md4hash(plaintext, ret_pwd);
+ E_md4hash((uchar *)plaintext, ret_pwd);
SAFE_FREE(plaintext);
return True;
}
@@ -429,9 +388,7 @@ BOOL secrets_store_ldap_pw(const char* dn, char* pw)
/**
- * Get trusted domains info from secrets.tdb.
- *
- * The linked list is allocated on the supplied talloc context, caller gets to destroy
+ * The linked list is allocated on the supplied talloc context, caller gets to destory
* when done.
*
* @param ctx Allocation context
@@ -452,11 +409,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
int start_idx;
uint32 idx = 0;
size_t size;
- fstring dom_name;
struct trusted_dom_pass *pass;
NTSTATUS status;
- if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
+ secrets_init();
*num_domains = 0;
start_idx = *enum_ctx;
@@ -499,10 +455,6 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
SAFE_FREE(pass);
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);
@@ -523,10 +475,6 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
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)++;
@@ -539,10 +487,6 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
/* 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++;
diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c
index 6ec1e48ab3..2c574f4a61 100644
--- a/source3/passdb/util_sam_sid.c
+++ b/source3/passdb/util_sam_sid.c
@@ -95,9 +95,6 @@ static void init_sid_name_map (void)
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 = global_myworkgroup;
sid_name_map[i].known_users = NULL;
i++;
diff --git a/source3/printing/load.c b/source3/printing/load.c
index cd90cbb6f3..ed967fb0a7 100644
--- a/source3/printing/load.c
+++ b/source3/printing/load.c
@@ -38,7 +38,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 +47,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/source3/printing/notify.c b/source3/printing/notify.c
index 925d49a21d..21e28d0ca7 100644
--- a/source3/printing/notify.c
+++ b/source3/printing/notify.c
@@ -3,7 +3,6 @@
Version 2.2
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
@@ -66,17 +65,18 @@ again:
/* Send message */
- tdb = conn_tdb_ctx();
+ tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
if (!tdb) {
DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n"));
- goto done;
+ return;
}
-
- message_send_all(tdb, MSG_PRINTER_NOTIFY2, buf, buflen, False, NULL);
-done:
+ message_send_all(tdb, MSG_PRINTER_NOTIFY2, buf,
+ buflen, False, NULL);
+
SAFE_FREE(buf);
+ tdb_close(tdb);
}
static void send_notify_field_values(const char *printer_name, uint32 type,
@@ -129,7 +129,7 @@ void notify_printer_status_byname(const char *printer_name, uint32 status)
void notify_printer_status(int snum, uint32 status)
{
- const char *printer_name = SERVICE(snum);
+ const char *printer_name = PRINTERNAME(snum);
if (printer_name)
notify_printer_status_byname(printer_name, status);
@@ -147,14 +147,14 @@ void notify_job_status_byname(const char *printer_name, uint32 jobid, uint32 sta
void notify_job_status(int snum, uint32 jobid, uint32 status)
{
- const char *printer_name = SERVICE(snum);
+ const char *printer_name = PRINTERNAME(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);
+ const char *printer_name = PRINTERNAME(snum);
/* Job id stored in id field, status in value1 */
@@ -165,7 +165,7 @@ void notify_job_total_bytes(int snum, uint32 jobid, uint32 size)
void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
{
- const char *printer_name = SERVICE(snum);
+ const char *printer_name = PRINTERNAME(snum);
/* Job id stored in id field, status in value1 */
@@ -176,7 +176,7 @@ void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
void notify_job_username(int snum, uint32 jobid, char *name)
{
- const char *printer_name = SERVICE(snum);
+ const char *printer_name = PRINTERNAME(snum);
send_notify_field_buffer(
printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
@@ -185,7 +185,7 @@ void notify_job_username(int snum, uint32 jobid, char *name)
void notify_job_name(int snum, uint32 jobid, char *name)
{
- const char *printer_name = SERVICE(snum);
+ const char *printer_name = PRINTERNAME(snum);
send_notify_field_buffer(
printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
@@ -194,54 +194,37 @@ void notify_job_name(int snum, uint32 jobid, char *name)
void notify_job_submitted(int snum, uint32 jobid, time_t submitted)
{
- const char *printer_name = SERVICE(snum);
+ const char *printer_name = PRINTERNAME(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)
+void notify_printer_delete(char *printer_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)
+void notify_printer_add(char *printer_name)
{
- 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)
+void notify_printer_driver(int num, char *driver_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)
+void notify_printer_comment(int num, char *comment)
{
- 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_sharename(int num, char *share_name)
+{
}
-void notify_printer_location(int snum, char *location)
+void notify_printer_port(int num, char *port_name)
{
- 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_location(int num, char *location)
+{
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index c497c65bfe..ff08b99eb0 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -319,17 +319,7 @@ BOOL nt_printing_init(void)
* 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
- */
-
- message_register( MSG_PRINTERDATA_INIT_RESET, reset_all_printerdata );
-
-
+ message_register(MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer);
return True;
}
@@ -445,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++;
}
@@ -1012,7 +998,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file,
}
close_file(fsp, True);
- if (use_version && (new_major != old_major || new_minor != old_minor)) {
+ if (use_version) {
/* Compare versions and choose the larger version number */
if (new_major > old_major ||
(new_major == old_major && new_minor > old_minor)) {
@@ -1232,7 +1218,8 @@ 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)
{
fstring architecture;
fstring new_name;
@@ -1287,7 +1274,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;
@@ -1962,52 +1950,22 @@ static 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;
}
@@ -2101,7 +2059,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;
@@ -2141,6 +2099,89 @@ 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.
****************************************************************************/
@@ -2241,7 +2282,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);
}
@@ -2251,29 +2292,23 @@ 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);
}
@@ -2353,257 +2388,32 @@ static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
}
/****************************************************************************
- allocate and initialize a new slot in
- ***************************************************************************/
-
-static int add_new_printer_key( NT_PRINTER_DATA *data, 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, 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 ( strcmp(data->keys[i].name, name) == 0 ) {
- DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
- key_index = i;
- break;
-
- }
- }
-
- return key_index;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2 )
-{
- WERROR result = WERR_OK;
- NT_PRINTER_DATA *data;
- int i;
-
- data = &p2->data;
-
- 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 );
- }
-
- SAFE_FREE( data->keys );
-
- DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
- p2->printername ));
-
- ZERO_STRUCTP( data );
-
- return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, 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 )
- key_index = add_new_printer_key( &p2->data, key );
-
- if ( key_index == -1 )
- return WERR_NOMEM;
-
- 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, char *key, 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, data, real_len );
-
- DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], size => [%d]\n",
- key, value, real_len ));
-
- return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, 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 = strchr( 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, data_p, size );
+ 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;
@@ -2837,10 +2647,10 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
info.devmode = construct_nt_devicemode(printername);
}
- 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);
@@ -3027,19 +2837,24 @@ 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;
/*
- * 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);
@@ -3049,7 +2864,7 @@ static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
kbuf.dsize = strlen(key)+1;
dbuf = tdb_fetch(tdb_drivers, kbuf);
- if (!dbuf.dptr) {
+ if (!dbuf.dptr) {
/*
* When changing to a driver that has no init info in the tdb, remove
* the previous drivers init info and leave the new on blank.
@@ -3118,10 +2933,9 @@ static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
info_ptr->printername, info_ptr->drivername));
/*
- * Add the printer data 'values' to the new printer
+ * Add the printer data 'specifics' to the new printer
*/
- len += unpack_values( &info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
-
+ len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
SAFE_FREE(dbuf.dptr);
@@ -3179,7 +2993,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
@@ -3200,7 +3014,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;
@@ -3231,14 +3045,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)
@@ -3263,6 +3077,154 @@ uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
}
/****************************************************************************
+ Convert the printer data value, a REG_BINARY array, into an initialization
+ DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
+ got to keep the endians happy :).
+****************************************************************************/
+
+static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
+{
+ BOOL result = False;
+ prs_struct ps;
+ DEVICEMODE devmode;
+
+ ZERO_STRUCT(devmode);
+
+ prs_init(&ps, 0, ctx, UNMARSHALL);
+ 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);
+ else
+ DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
+
+ return result;
+}
+
+/****************************************************************************
+ Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
+
+ 1. Use the driver's config DLL to this UNC printername and:
+ a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
+ b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
+ 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
+
+ The last step triggers saving the "driver initialization" information for
+ this printer into the tdb. Later, new printers that use this driver will
+ have this initialization information bound to them. This simulates the
+ driver initialization, as if it had run on the Samba server (as it would
+ have done on NT).
+
+ The Win32 client side code requirement sucks! But until we can run arbitrary
+ Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
+
+ It would have been easier to use SetPrinter because all the UNMARSHALLING of
+ the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
+ about it and you will realize why. JRR 010720
+****************************************************************************/
+
+static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
+{
+ WERROR status = WERR_OK;
+ TALLOC_CTX *ctx = NULL;
+ NT_DEVICEMODE *nt_devmode = NULL;
+ NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
+
+ /*
+ * When the DEVMODE is already set on the printer, don't try to unpack it.
+ */
+
+ 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()) == 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(param, ctx, nt_devmode)) {
+ DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
+ status = WERR_INVALID_PARAM;
+ goto done;
+ }
+
+ printer->info_2->devmode = nt_devmode;
+ }
+
+ /*
+ * Pack up and add (or update) the DEVMODE and any current printer data to
+ * a 'driver init' element in the tdb
+ *
+ */
+
+ if (update_driver_init(*printer, 2)!=0) {
+ DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
+ status = WERR_NOMEM;
+ goto done;
+ }
+
+ /*
+ * If driver initialization info was successfully saved, set the current
+ * printer to match it. This allows initialization of the current printer
+ * as well as the driver.
+ */
+ status = mod_a_printer(*printer, 2);
+ if (!W_ERROR_IS_OK(status)) {
+ DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
+ printer->info_2->printername));
+ }
+
+#if 0 /* JERRY */
+ srv_spoolss_sendnotify(p, handle);
+#endif
+
+ done:
+ talloc_destroy(ctx);
+ if (nt_devmode)
+ SAFE_FREE(nt_devmode->private);
+ SAFE_FREE(nt_devmode);
+ printer->info_2->devmode = tmp_devmode;
+
+ return status;
+}
+
+/****************************************************************************
+ Update the driver init info (DEVMODE and specifics) for a printer
+****************************************************************************/
+
+WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
+{
+ WERROR status = WERR_OK;
+
+ switch (level)
+ {
+ case 2:
+ {
+ status=save_driver_init_2(printer, param);
+ break;
+ }
+ default:
+ status=WERR_UNKNOWN_LEVEL;
+ break;
+ }
+
+ return status;
+}
+
+/****************************************************************************
Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
****************************************************************************/
@@ -3790,7 +3752,7 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i,
{
pstring key;
fstring arch;
- TDB_DATA kbuf, dbuf;
+ TDB_DATA kbuf;
NT_PRINTER_DRIVER_INFO_LEVEL ctr;
/* delete the tdb data first */
@@ -3808,20 +3770,8 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i,
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
- /* check if the driver actually exists for this environment */
-
- dbuf = tdb_fetch( tdb_drivers, kbuf );
- if ( !dbuf.dptr ) {
- DEBUG(8,("delete_printer_driver_internal: Driver unknown [%s]\n", key));
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- SAFE_FREE( dbuf.dptr );
-
- /* ok... the driver exists so the delete should return success */
-
if (tdb_delete(tdb_drivers, kbuf) == -1) {
- DEBUG (0,("delete_printer_driver_internal: fail to delete %s!\n", key));
+ DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
return WERR_ACCESS_DENIED;
}
@@ -3834,8 +3784,8 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i,
if ( delete_files )
delete_driver_files( i, user );
-
- DEBUG(5,("delete_printer_driver_internal: driver delete successful [%s]\n", key));
+ DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
+ i->name));
return WERR_OK;
}
@@ -3848,33 +3798,99 @@ static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i,
WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user,
uint32 version, BOOL delete_files )
{
+ int ver;
WERROR err;
- /*
- * see if we should delete all versions of this driver
- * (DRIVER_ANY_VERSION uis only set for "Windows NT x86")
- */
+ /* see if we should delete all versions of this driver */
- if ( version == DRIVER_ANY_VERSION )
- {
- /* Windows NT 4.0 */
-
- err = delete_printer_driver_internal(i, user, 2, delete_files );
- if ( !W_ERROR_IS_OK(err) && (W_ERROR_V(err) != ERRunknownprinterdriver ) )
- return err;
-
- /* Windows 2000/XP */
-
- err = delete_printer_driver_internal(i, user, 3, delete_files );
- if ( !W_ERROR_IS_OK(err) && (W_ERROR_V(err) != ERRunknownprinterdriver ) )
+ if ( version == DRIVER_ANY_VERSION ) {
+ for ( ver=0; ver<DRIVER_MAX_VERSION; ver++ ) {
+ err = delete_printer_driver_internal(i, user, ver, delete_files );
+ if ( !W_ERROR_IS_OK(err) )
return err;
+ }
+ }
+ else
+ delete_printer_driver_internal(i, user, version, delete_files );
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++;
}
- /* just delete what they asked for */
+ 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;
+ }
- return delete_printer_driver_internal(i, user, version, delete_files );
+ 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);
}
/****************************************************************************
@@ -4312,3 +4328,76 @@ 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/source3/printing/pcap.c b/source3/printing/pcap.c
index 86489e9587..4bca63fffb 100644
--- a/source3/printing/pcap.c
+++ b/source3/printing/pcap.c
@@ -241,12 +241,15 @@ 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, char *pszPrintcapname)
{
char *line=NULL;
- const char *psz;
+ char *psz;
char *p,*q;
XFILE *pfile;
@@ -302,6 +305,8 @@ BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname
if (strequal(p,pszPrintername))
{
+ /* normalise the case */
+ pstrcpy(pszPrintername,p);
SAFE_FREE(line);
x_fclose(pfile);
return(True);
diff --git a/source3/printing/print_svid.c b/source3/printing/print_svid.c
index 837a2fba48..44127c3700 100644
--- a/source3/printing/print_svid.c
+++ b/source3/printing/print_svid.c
@@ -126,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/source3/printing/printfsp.c b/source3/printing/printfsp.c
index ff50ac47c4..9f33d57ad5 100644
--- a/source3/printing/printfsp.c
+++ b/source3/printing/printfsp.c
@@ -54,7 +54,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
/* setup a full fsp */
fsp->print_jobid = jobid;
- fsp->fd = print_job_fd(SNUM(conn),jobid);
+ fsp->fd = print_job_fd(jobid);
GetTimeOfDay(&fsp->open_time);
fsp->vuid = current_user.vuid;
fsp->size = 0;
@@ -70,7 +70,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
fsp->is_directory = False;
fsp->directory_delete_on_close = False;
fsp->conn = conn;
- string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid));
+ string_set(&fsp->fsp_name,print_job_fname(jobid));
fsp->wbmpx_ptr = NULL;
fsp->wcp = NULL;
conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
@@ -96,7 +96,7 @@ void print_fsp_end(files_struct *fsp, BOOL normal_close)
sys_ftruncate(fsp->fd, 0);
}
- print_job_end(SNUM(fsp->conn),fsp->print_jobid, normal_close);
+ print_job_end(fsp->print_jobid, normal_close);
if (fsp->fsp_name) {
string_free(&fsp->fsp_name);
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index cb689c05d6..7bfce43af6 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -39,97 +39,98 @@ static struct printif *current_printif = &generic_printif;
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 pid_t local_pid;
+
+/* Mapping between printer names and queue id's in job id's. */
+struct printer_queueid_map {
+ struct printer_queueid_map *next, *prev;
+ char *printername;
+ uint32 queueid;
+};
+
+static struct printer_queueid_map *printer_queueid_map_head;
+static uint32 last_queueid;
-static TDB_CONTEXT *rap_tdb;
-static uint16 next_rap_jobid;
+#define QUEUEID_BITS 12
+#define QUEUEID_MASK ((1<<(QUEUEID_BITS))-1)
+#define QUEUEID_TO_JOBID(queueid) (((queueid) & QUEUEID_MASK) << 20 )
-uint16 pjobid_to_rap(int snum, uint32 jobid)
+/****************************************************************************
+ Create an association between a printer name and a queueid. Used to encode
+ the printer queueid in jobid's.
+ This could be converted to use an internal tdb if searching the list is
+ too slow. JRA.
+****************************************************************************/
+
+BOOL create_printer_queueid(const char *printername)
{
- uint16 rap_jobid;
- TDB_DATA data, key;
- char jinfo[8];
+ struct printer_queueid_map *p;
- 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;
+ for (p = printer_queueid_map_head; p; p = p->next) {
+ if (strequal(p->printername, printername))
+ return True;
}
- 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)) {
- memcpy(&rap_jobid, data.dptr, sizeof(uint16));
- SAFE_FREE(data.dptr);
- return rap_jobid;
+ p = (struct printer_queueid_map *)malloc(sizeof(*p));
+ if (!p) {
+ DEBUG(0,("create_printer_queueid: malloc fail !\n"));
+ return False;
+ }
+ ZERO_STRUCTP(p);
+ p->printername = strdup(printername);
+ if (!p->printername) {
+ DEBUG(0,("create_printer_queueid: malloc fail !\n"));
+ SAFE_FREE(p);
+ return False;
}
- /* 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);
- return rap_jobid;
+ p->queueid = (++last_queueid);
+ if (p->queueid > QUEUEID_MASK) {
+ DEBUG(0,("create_printer_queueid: malloc fail !\n"));
+ SAFE_FREE(p->printername);
+ SAFE_FREE(p);
+ return False;
+ }
+ DLIST_ADD(printer_queueid_map_head, p);
+ return True;
}
-BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
+void set_register_printer_fn(void)
{
- TDB_DATA data, key;
- char jinfo[8];
-
- 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 == sizeof(jinfo)) {
- *psnum = IVAL(&jinfo,0);
- *pjobid = IVAL(&jinfo,4);
- SAFE_FREE(data.dptr);
- return True;
- }
- return False;
+ extern BOOL (*register_printer_fn)(const char *);
+ register_printer_fn = create_printer_queueid;
}
-static void rap_jobid_delete(int snum, uint32 jobid)
+/****************************************************************************
+ Lookups.
+****************************************************************************/
+
+static uint32 get_printer_queueid_byname(const char *printername)
{
- TDB_DATA key, data;
- uint16 rap_jobid;
- char jinfo[8];
+ struct printer_queueid_map *p;
- if (!rap_tdb)
- return;
+ for (p = printer_queueid_map_head; p; p = p->next) {
+ if (strequal(p->printername, printername))
+ return p->queueid;
+ }
+ return 0;
+}
- SIVAL(&jinfo,0,(int32)snum);
- SIVAL(&jinfo,4,jobid);
+/****************************************************************************
+ Lookups.
+****************************************************************************/
- key.dptr = (char *)&jinfo;
- key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
- if (!data.dptr || (data.dsize != sizeof(uint16)))
- return;
+static const char *get_printer_name_byjobid(uint32 jobid)
+{
+ struct printer_queueid_map *p;
+ uint32 queueid = (((jobid)>>20) & QUEUEID_MASK);
- memcpy(&rap_jobid, data.dptr, sizeof(uint16));
- SAFE_FREE(data.dptr);
- data.dptr = (char *)&rap_jobid;
- data.dsize = sizeof(rap_jobid);
- tdb_delete(rap_tdb, key);
- tdb_delete(rap_tdb, data);
+ for (p = printer_queueid_map_head; p; p = p->next) {
+ if (p->queueid == queueid)
+ return p->printername;
+ }
+ return NULL;
}
-static pid_t local_pid;
-
static int get_queue_status(int, print_status_struct *);
#define MAX_PRINT_DBS_OPEN 1
@@ -185,14 +186,9 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
DLIST_ADD(print_db_head, p);
}
- pstrcpy(printdb_path, lock_path("printing/"));
- pstrcat(printdb_path, printername);
+ pstrcpy(printdb_path, lock_path(printername));
pstrcat(printdb_path, ".tdb");
-
- become_root();
p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- unbecome_root();
-
if (!p->tdb) {
DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
printdb_path ));
@@ -204,6 +200,14 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
return p;
}
+static struct tdb_print_db *get_print_db_byjobid( uint32 jobid)
+{
+ const char *printername = get_printer_name_byjobid(jobid);
+ if (!printername)
+ return NULL;
+ return get_print_db_byname(printername);
+}
+
/****************************************************************************
Initialise the printing backend. Called once at startup.
Does not survive a fork
@@ -211,28 +215,20 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
BOOL print_backend_init(void)
{
+ struct printer_queueid_map *p;
char *sversion = "INFO/version";
- pstring printing_path;
- int services = lp_numservices();
- int snum;
if (local_pid == sys_getpid())
return True;
unlink(lock_path("printing.tdb"));
- pstrcpy(printing_path,lock_path("printing"));
- mkdir(printing_path,0755);
-
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;
+ for (p = printer_queueid_map_head; p; p = p->next) {
+ struct tdb_print_db *pdb = get_print_db_byname(p->printername);
- pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
continue;
tdb_lock_bystring(pdb->tdb, sversion);
@@ -290,11 +286,11 @@ static TDB_DATA print_key(uint32 jobid)
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(uint32 jobid)
{
static struct printjob pjob;
TDB_DATA ret;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
+ struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
if (!pdb)
return NULL;
@@ -338,16 +334,11 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
uint32 sysjob_to_jobid(int unix_jobid)
{
- int services = lp_numservices();
- int snum;
-
+ struct printer_queueid_map *p;
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));
+ for (p = printer_queueid_map_head; p; p = p->next) {
+ struct tdb_print_db *pdb = get_print_db_byname(p->printername);
if (pdb)
tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
if (sysjob_to_jobid_value != (uint32)-1)
@@ -394,10 +385,14 @@ static uint32 map_to_spoolss_status(uint32 lpq_status)
return 0;
}
-static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
+static void pjob_store_notify(uint32 jobid, struct printjob *old_data,
struct printjob *new_data)
{
BOOL new_job = False;
+ int snum = print_job_snum(jobid);
+
+ if (snum == -1)
+ return;
if (!old_data)
new_job = True;
@@ -432,11 +427,11 @@ static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
Store a job structure back to the database.
****************************************************************************/
-static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
+static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
{
TDB_DATA old_data, new_data;
BOOL ret;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
+ struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
if (!pdb)
return False;
@@ -455,7 +450,7 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) {
pjob_store_notify(
- snum, jobid, (struct printjob *)old_data.dptr,
+ jobid, (struct printjob *)old_data.dptr,
(struct printjob *)new_data.dptr);
free(old_data.dptr);
}
@@ -467,11 +462,12 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
Remove a job structure from the database.
****************************************************************************/
-static void pjob_delete(int snum, uint32 jobid)
+static void pjob_delete(uint32 jobid)
{
- struct printjob *pjob = print_job_find(snum, jobid);
+ int snum;
+ struct printjob *pjob = print_job_find(jobid);
uint32 job_status = 0;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
+ struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
if (!pdb)
return;
@@ -490,6 +486,7 @@ static void pjob_delete(int snum, uint32 jobid)
JOB_STATUS_DELETED for the port monitor to delete the job
properly. */
+ snum = print_job_snum(jobid);
job_status |= JOB_STATUS_DELETING;
notify_job_status(snum, jobid, job_status);
@@ -499,7 +496,6 @@ static void pjob_delete(int snum, uint32 jobid)
/* Remove from printing.tdb */
tdb_delete(pdb->tdb, print_key(jobid));
- rap_jobid_delete(snum, jobid);
}
/****************************************************************************
@@ -527,12 +523,13 @@ static uint32 print_parse_jobid(char *fname)
static void print_unix_job(int snum, print_queue_struct *q)
{
- uint32 jobid = q->job + UNIX_JOB_START;
+ uint32 queueid = get_printer_queueid_byname(PRINTERNAME(snum));
+ uint32 jobid = (q->job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid);
struct printjob pj, *old_pj;
/* 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);
@@ -549,7 +546,7 @@ static void print_unix_job(int snum, print_queue_struct *q)
fstrcpy(pj.user, q->fs_user);
fstrcpy(pj.queuename, lp_const_servicename(snum));
- pjob_store(snum, jobid, &pj);
+ pjob_store(jobid, &pj);
}
@@ -564,6 +561,7 @@ struct traverse_struct {
static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
{
+ uint32 queueid;
struct traverse_struct *ts = (struct traverse_struct *)state;
struct printjob pjob;
uint32 jobid;
@@ -579,16 +577,18 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
return 0;
}
+ queueid = get_printer_queueid_byname(pjob.queuename);
+
if (!pjob.smbjob) {
/* 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);
+ uint32 u_jobid = ((ts->queue[i].job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid));
if (jobid == u_jobid)
break;
}
if (i == ts->qcount)
- pjob_delete(ts->snum, jobid);
+ pjob_delete(jobid);
else
ts->total_jobs++;
return 0;
@@ -600,14 +600,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
exist then kill it. This cleans up after smbd
deaths */
if (!process_exists(pjob.pid))
- pjob_delete(ts->snum, jobid);
+ pjob_delete(jobid);
else
ts->total_jobs++;
return 0;
}
for (i=0;i<ts->qcount;i++) {
- uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
+ uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file) | QUEUEID_TO_JOBID(queueid);
if (jobid == curr_jobid)
break;
}
@@ -627,7 +627,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
submitted less than lp_lpqcachetime() seconds ago. */
if ((cur_t - pjob.starttime) > lp_lpqcachetime())
- pjob_delete(ts->snum, jobid);
+ pjob_delete(jobid);
else
ts->total_jobs++;
}
@@ -688,7 +688,7 @@ static pid_t get_updating_pid(fstring printer_name)
in the 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;
@@ -813,7 +813,7 @@ static void print_queue_update(int snum)
}
/* 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
@@ -825,7 +825,7 @@ static void print_queue_update(int snum)
pjob->sysjob = queue[i].job;
pjob->status = queue[i].status;
- pjob_store(snum, jobid, pjob);
+ pjob_store(jobid, pjob);
}
/* now delete any queued entries that don't appear in the
@@ -871,21 +871,36 @@ static void print_queue_update(int snum)
Check if a jobid is valid. It is valid if it exists in the database.
****************************************************************************/
-BOOL print_job_exists(int snum, uint32 jobid)
+BOOL print_job_exists(uint32 jobid)
{
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
+ struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
if (!pdb)
return False;
return tdb_exists(pdb->tdb, print_key(jobid));
}
/****************************************************************************
+ 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.
+****************************************************************************/
+
+int print_job_snum(uint32 jobid)
+{
+ struct printjob *pjob = print_job_find(jobid);
+ if (!pjob)
+ return -1;
+
+ return find_service(pjob->queuename);
+}
+
+/****************************************************************************
Give the fd used for a jobid.
****************************************************************************/
-int print_job_fd(int snum, uint32 jobid)
+int print_job_fd(uint32 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 */
@@ -900,9 +915,9 @@ int print_job_fd(int snum, uint32 jobid)
has not been spooled.
****************************************************************************/
-char *print_job_fname(int snum, uint32 jobid)
+char *print_job_fname(uint32 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;
@@ -912,7 +927,7 @@ char *print_job_fname(int snum, uint32 jobid)
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(uint32 jobid, int place)
{
DEBUG(2,("print_job_set_place not implemented yet\n"));
return False;
@@ -922,24 +937,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(uint32 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);
+ return pjob_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(uint32 jobid)
{
- struct printjob *pjob = print_job_find(snum, jobid);
- int result = 0;
+ struct printjob *pjob = print_job_find(jobid);
+ int snum, result = 0;
if (!pjob)
return False;
@@ -951,6 +966,12 @@ 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 %u\n", (unsigned int)jobid));
+ return False;
+ }
+
/* Hrm - we need to be able to cope with deleting a job before it
has reached the spooler. */
@@ -961,7 +982,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
/* Set the tdb entry to be deleting. */
pjob->status = LPQ_DELETING;
- pjob_store(snum, jobid, pjob);
+ pjob_store(jobid, pjob);
if (pjob->spooled && pjob->sysjob != -1)
result = (*(current_printif->job_delete))(snum, pjob);
@@ -970,7 +991,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
been spooled. */
if (result == 0)
- pjob_delete(snum, jobid);
+ pjob_delete(jobid);
return (result == 0);
}
@@ -979,9 +1000,9 @@ 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, uint32 jobid)
{
- struct printjob *pjob = print_job_find(snum, jobid);
+ struct printjob *pjob = print_job_find(jobid);
user_struct *vuser;
if (!pjob || !user)
@@ -998,11 +1019,17 @@ 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, uint32 jobid, WERROR *errcode)
{
+ int snum = print_job_snum(jobid);
BOOL owner;
- 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. */
@@ -1014,7 +1041,7 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR
return False;
}
- if (!print_job_delete1(snum, jobid))
+ if (!print_job_delete1(jobid))
return False;
/* force update the database and say the delete failed if the
@@ -1022,17 +1049,17 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR
print_queue_update(snum);
- return !print_job_exists(snum, jobid);
+ 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, uint32 jobid, WERROR *errcode)
{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret = -1;
+ struct printjob *pjob = print_job_find(jobid);
+ int snum, ret = -1;
if (!pjob || !user)
return False;
@@ -1040,7 +1067,13 @@ BOOL print_job_pause(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_pause: unknown service number for jobid %u\n", (unsigned int)jobid));
+ return False;
+ }
+
+ if (!is_owner(user, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("pause denied by security descriptor\n"));
*errcode = WERR_ACCESS_DENIED;
@@ -1071,10 +1104,10 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *
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, uint32 jobid, WERROR *errcode)
{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret;
+ struct printjob *pjob = print_job_find(jobid);
+ int snum, ret;
if (!pjob || !user)
return False;
@@ -1082,7 +1115,13 @@ 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 %u\n", (unsigned int)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;
@@ -1110,10 +1149,10 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR
Write to a print file.
****************************************************************************/
-int print_job_write(int snum, uint32 jobid, const char *buf, int size)
+int print_job_write(uint32 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;
@@ -1124,7 +1163,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);
+ pjob_store(jobid, pjob);
}
return return_code;
}
@@ -1221,24 +1260,18 @@ int print_queue_length(int snum, print_status_struct *pstatus)
static int get_total_jobs(void)
{
- int total_jobs = 0;
- int snum;
- int services = lp_numservices();
+ int total_jobs;
+ struct printer_queueid_map *p;
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
+ for (p = printer_queueid_map_head; p; p = p->next) {
int jobs;
-
- if (!lp_print_ok(snum))
- continue;
-
- pdb = get_print_db_byname(lp_const_servicename(snum));
+ struct tdb_print_db *pdb = get_print_db_byname(p->printername);
if (!pdb)
continue;
/* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
+ if (print_cache_expired(lp_servicenumber(p->printername)))
+ print_queue_update(lp_servicenumber(p->printername));
jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
if (jobs > 0)
@@ -1261,6 +1294,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
int njobs = 0;
const char *printername = lp_const_servicename(snum);
struct tdb_print_db *pdb = get_print_db_byname(printername);
+ uint32 queueid = queueid = get_printer_queueid_byname(printername);
errno = 0;
@@ -1342,10 +1376,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
next_jobid = 1;
for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
- if (!print_job_exists(snum, jobid))
+ if (!print_job_exists(jobid | QUEUEID_TO_JOBID(queueid)))
break;
}
- if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) {
+ if (jobid == next_jobid || !pjob_store(jobid | QUEUEID_TO_JOBID(queueid), &pjob)) {
DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n",
jobid, next_jobid ));
jobid = -1;
@@ -1358,6 +1392,9 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
goto fail;
}
+ /* Ensure the queuid is added to the jobid. */
+ jobid |= QUEUEID_TO_JOBID(queueid);
+
/* 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);
@@ -1376,7 +1413,7 @@ to open spool file %s.\n", pjob.filename));
goto fail;
}
- pjob_store(snum, jobid, &pjob);
+ pjob_store(jobid, &pjob);
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
@@ -1388,14 +1425,14 @@ to open spool file %s.\n", pjob.filename));
* tim@fsg.com 09/06/94
*/
if (lp_postscript(snum)) {
- print_job_write(snum, jobid, "%!\n",3);
+ print_job_write(jobid, "%!\n",3);
}
return jobid;
fail:
if (jobid != -1)
- pjob_delete(snum, jobid);
+ pjob_delete(jobid);
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
@@ -1407,9 +1444,9 @@ to open spool file %s.\n", pjob.filename));
Update the number of pages spooled to jobid
****************************************************************************/
-void print_job_endpage(int snum, uint32 jobid)
+void print_job_endpage(uint32 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 */
@@ -1417,7 +1454,7 @@ void print_job_endpage(int snum, uint32 jobid)
return;
pjob->page_count++;
- pjob_store(snum, jobid, pjob);
+ pjob_store(jobid, pjob);
}
/****************************************************************************
@@ -1426,10 +1463,10 @@ void print_job_endpage(int snum, uint32 jobid)
error.
****************************************************************************/
-BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
+BOOL print_job_end(uint32 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;
if (!pjob)
@@ -1438,6 +1475,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 %u\n", (unsigned int)jobid));
+ return False;
+ }
+
if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
pjob->size = sbuf.st_size;
close(pjob->fd);
@@ -1462,7 +1505,7 @@ 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);
+ pjob_delete(jobid);
return True;
}
@@ -1475,7 +1518,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
pjob->spooled = True;
pjob->status = LPQ_QUEUED;
- pjob_store(snum, jobid, pjob);
+ pjob_store(jobid, pjob);
/* make sure the database is up to date */
if (print_cache_expired(snum))
@@ -1488,7 +1531,7 @@ 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);
+ pjob_delete(jobid);
return False;
}
@@ -1750,10 +1793,10 @@ 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);
}
}
diff --git a/source3/python/.cvsignore b/source3/python/.cvsignore
deleted file mode 100644
index 659ddbfdf9..0000000000
--- a/source3/python/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-setup.py
diff --git a/source3/python/examples/spoolss/changeid.py b/source3/python/examples/spoolss/changeid.py
deleted file mode 100755
index b2345094ed..0000000000
--- a/source3/python/examples/spoolss/changeid.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/python
-#
-# Display the changeid for a list of printers given on the command line
-#
-
-import sys, 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/source3/python/examples/spoolss/enumprinters.py b/source3/python/examples/spoolss/enumprinters.py
deleted file mode 100755
index bf08b95bb9..0000000000
--- a/source3/python/examples/spoolss/enumprinters.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-#
-# Display information on all printers on a print server
-#
-
-import sys, spoolss
-
-if len(sys.argv) != 2:
- print "Usage: changeid.py <printername>"
- sys.exit(1)
-
-printserver = sys.argv[1]
-
-# Get list of printers
-
-try:
- printer_list = spoolss.enumprinters(printserver)
-except:
- print "error enumerating printers on %s" % printserver
- sys.exit(1)
-
-# Display basic info
-
-for printer in printer_list:
- print "%s: %s" % (printer["printer_name"], printer["comment"])
diff --git a/source3/python/examples/spoolss/psec.py b/source3/python/examples/spoolss/psec.py
deleted file mode 100755
index f3fdb7bccd..0000000000
--- a/source3/python/examples/spoolss/psec.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env python
-#
-# Get or set the security descriptor on a printer
-#
-
-import sys, spoolss, re, string
-
-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/source3/python/gtdbtool b/source3/python/gtdbtool
deleted file mode 100755
index 792cdeecc0..0000000000
--- a/source3/python/gtdbtool
+++ /dev/null
@@ -1,282 +0,0 @@
-#!/usr/bin/env python
-
-from gtk import *
-import sys
-import tdb
-import string
-import re
-
-#
-# The gdbtool user interface. The design here is to keep all the gtk stuff
-# separate from the tdb stuff so all the user interface magic is stored
-# here.
-#
-
-class gtdbtool:
-
- # Initialise the user interface. A dictionary argument is passed
- # in which is the dictionary to display keys and values on the left
- # hand and right hand side of the user interface respectively."""
-
- def __init__(self, dict):
- self.dict = dict
- self.value_display_fns = []
- 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.display_key(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, text):
- self.text.delete_text(0, self.text.get_length())
-
- # The text widget has trouble inserting text containing NULL
- # characters.
-
- text = string.replace(text, "\x00", ".")
-
- self.text.insert(self.font, None, None, text)
-
- # 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 = t[list_item.get_data("raw_key")]
-
- for entry in self.value_display_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()
-
- #
- # Public methods
- #
-
- # Set a function that translates between how keys look in the user
- # interface (displayed keys) versus how they are represented in the tdb
- # (raw keys).
-
- def set_display_key_fn(self, fn):
- self.display_key = fn
-
- # Register a value display function for a key. The first argument is a
- # regex that matches key values, and the second argument is a function
- # to call to convert the raw value data to a string to display in the
- # right hand side of the UI.
-
- def register_display_value_fn(self, key_regexp, fn):
- self.value_display_fns.append((key_regexp, fn))
-
- def display_value_hex(self, value):
- return "foo"
-
-def convert_to_hex(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
-
-# 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 user interface
-
-w = gtdbtool(t)
-
-# Set up a key display function. A lot of keys have \x00 appended to the
-# end which mucks up gtk.
-
-def display_key_x00(key):
- return string.replace(key, "\x00", "")
-
-w.set_display_key_fn(display_key_x00)
-
-def display_value_hex(value):
- return value;
-
-w.register_display_value_fn("DRIVERS/", convert_to_hex)
-w.register_display_value_fn("SECDESC/", convert_to_hex)
-w.register_display_value_fn("PRINTERS/", convert_to_hex)
-
-# Show user interface
-
-w.build_ui("gtdbtool: %s" % sys.argv[1])
-
-# 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/source3/python/py_common.c b/source3/python/py_common.c
deleted file mode 100644
index a65206e022..0000000000
--- a/source3/python/py_common.c
+++ /dev/null
@@ -1,255 +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 "includes.h"
-#include "Python.h"
-
-#include "python/py_common_proto.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)
-{
- extern pstring global_myname;
- char *p;
-
- 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();
-
- fstrcpy(global_myname, myhostname());
- p = strchr(global_myname, '.');
- if (p)
- *p = 0;
-
- 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;
-
- /* 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;
- }
-
- /* Look for any other fields */
-
- /* 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;
- }
-
- /* 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,
- char *pipe_name, char **errstr)
-{
- char *username, *password, *domain;
- struct cli_state *cli;
- NTSTATUS result;
-
- /* Extract credentials from the python dictionary */
-
- if (!py_parse_creds(creds, &username, &password, &domain, errstr))
- return NULL;
-
- /* Now try to connect */
-
- result = cli_full_connection(
- &cli, NULL, server, NULL, 0, "IPC$", "IPC",
- username, domain, password, 0);
-
- if (!NT_STATUS_IS_OK(result)) {
- *errstr = strdup("error connecting to IPC$ pipe");
- return NULL;
- }
-
- if (!cli_nt_session_open(cli, pipe_name)) {
- cli_shutdown(cli);
- free(cli);
- asprintf(errstr, "error opening %s", pipe_name);
- 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/source3/python/py_conv.c b/source3/python/py_conv.c
deleted file mode 100644
index 39b20ace86..0000000000
--- a/source3/python/py_conv.c
+++ /dev/null
@@ -1,159 +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 "includes.h"
-#include "Python.h"
-#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);
-}
-
-/* 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 s = "";
-
- if (u->buffer)
- fstr_pull(s, u);
-
- item = PyString_FromString(s);
- 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;
- }
- 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 *s = "";
-
- if (!PyString_Check(obj))
- goto done;
-
- s = PyString_AsString(obj);
- init_unistr(u, s);
-
- 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;
-}
diff --git a/source3/python/py_samr.c b/source3/python/py_samr.c
deleted file mode 100644
index ce6eda99c2..0000000000
--- a/source3/python/py_samr.c
+++ /dev/null
@@ -1,456 +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 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())) {
- 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 PyMethodDef samr_domain_methods[] = {
- { 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 */
-};
-
-/* SAMR user handle object */
-
-static void py_samr_user_hnd_dealloc(PyObject* self)
-{
- PyObject_Del(self);
-}
-
-static PyMethodDef samr_user_methods[] = {
- { 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 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;
-}
-
-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, PIPE_SAMR, &errstr))) {
- PyErr_SetString(samr_error, errstr);
- free(errstr);
- return NULL;
- }
-
- if (!(mem_ctx = talloc_init())) {
- 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);
- SAFE_FREE(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[] = {
- { 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/source3/python/py_spoolss.c b/source3/python/py_spoolss.c
deleted file mode 100644
index 95be77de55..0000000000
--- a/source3/python/py_spoolss.c
+++ /dev/null
@@ -1,478 +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;
-
-/*
- * Routines to convert from python hashes to Samba structures
- */
-
-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;
-}
-
-/*
- * 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.
-
-Optionally a dictionary of (domain, username, password) may be given in
-which case they are used when opening the RPC pipe. An access mask may
-also be given which defaults to MAXIMUM_ALLOWED_ACCESS.
-
-Example:
-
->>> hnd = spoolss.openprinter(\"\\\\\\\\NPSD-PDC2\\\\meanie\")"},
-
- { "closeprinter", spoolss_closeprinter, METH_VARARGS,
- "Close a printer handle opened with openprinter or addprinter.
-
-Example:
-
->>> 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.
-
-Return a list of printers on a print server. The credentials, info level
-and flags may be specified as keyword arguments.
-
-Example:
-
->>> print spoolss.enumprinters(\"\\\\\\\\npsd-pdc2\")
-[{'comment': 'i am a comment', 'printer_name': 'meanie', 'flags': 8388608,
- 'description': 'meanie,Generic / Text Only,i am a location'},
- {'comment': '', 'printer_name': 'fileprint', 'flags': 8388608,
- 'description': 'fileprint,Generic / Text Only,'}]"},
-
- { "enumports", (PyCFunction)spoolss_enumports,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate ports on a print server.
-
-Return a list of ports on a print server.
-
-Example:
-
->>> print spoolss.enumports(\"\\\\\\\\npsd-pdc2\")
-[{'name': 'LPT1:'}, {'name': 'LPT2:'}, {'name': 'COM1:'}, {'name': 'COM2:'},
- {'name': 'FILE:'}, {'name': '\\\\nautilus1\\zpekt3r'}]"},
-
- { "enumprinterdrivers", (PyCFunction)spoolss_enumprinterdrivers,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate printer drivers on a print server.
-
-Return a list of printer drivers."},
- /* Miscellaneous other commands */
-
- { "getprinterdriverdir", (PyCFunction)spoolss_getprinterdriverdir,
- METH_VARARGS | METH_KEYWORDS,
- "Return printer driver directory.
-
-Return the printer driver directory for a given architecture. The
-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.
-
-Initialises Samba's debug logging system. One argument is expected which
-is a boolean specifying whether debugging is interactive and sent to stdout
-or logged to a file.
-
-Example:
-
->>> spoolss.setup_logging(interactive = 1)" },
-
- { "get_debuglevel", (PyCFunction)get_debuglevel,
- METH_VARARGS,
- "Set the current debug level.
-
-Example:
-
->>> spoolss.get_debuglevel()
-0" },
-
- { "set_debuglevel", (PyCFunction)set_debuglevel,
- METH_VARARGS,
- "Get the current debug level.
-
-Example:
-
->>> 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.
-
-Return a dictionary of print information. The info level defaults to 1.
-
-Example:
-
->>> hnd.getprinter()
-{'comment': 'i am a comment', 'printer_name': '\\\\NPSD-PDC2\\meanie',
- 'description': '\\\\NPSD-PDC2\\meanie,Generic / Text Only,i am a location',
- '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.
-
-Return a dictionary of printer driver information for the printer driver
-bound to this printer."},
-
- /* Forms */
-
- { "enumforms", (PyCFunction)spoolss_hnd_enumforms,
- METH_VARARGS | METH_KEYWORDS,
- "Enumerate supported forms.
-
-Return a list of forms supported by this printer or print server."},
-
- { "setform", (PyCFunction)spoolss_hnd_setform,
- METH_VARARGS | METH_KEYWORDS,
- "Set form data.
-
-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." },
-
- { "deleteprinterdataex", (PyCFunction)spoolss_hnd_deleteprinterdataex,
- METH_VARARGS | METH_KEYWORDS,
- "Delete printer data." },
-
- { 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/source3/python/py_spoolss_drivers.c b/source3/python/py_spoolss_drivers.c
deleted file mode 100644
index b5357a78ad..0000000000
--- a/source3/python/py_spoolss_drivers.c
+++ /dev/null
@@ -1,434 +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, PIPE_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init())) {
- 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(
- value, "level", PyInt_FromLong(1));
-
- 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(
- value, "level", PyInt_FromLong(2));
-
- 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(
- value, "level", PyInt_FromLong(3));
-
- 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]);
-
- PyDict_SetItemString(
- value, "level", PyInt_FromLong(6));
-
- 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";
- 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,
- arch, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_getprinterdriver(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
- level, 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, PIPE_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init())) {
- 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);
- PyDict_SetItemString(
- result, "level", PyInt_FromLong(1));
- 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())) {
- PyErr_SetString(
- spoolss_error, "unable to init talloc context\n");
- return NULL;
- }
-
- if (!(cli = open_pipe_creds(server, creds, PIPE_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);
-
- 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/source3/python/py_spoolss_drivers_conv.c b/source3/python/py_spoolss_drivers_conv.c
deleted file mode 100644
index dbf33905ae..0000000000
--- a/source3/python/py_spoolss_drivers_conv.c
+++ /dev/null
@@ -1,148 +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) },
- /* dependentfiles */
- { "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) },
- /* dependentfiles */
- { "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 }
-};
-
-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));
- return True;
-}
-
-BOOL py_to_DRIVER_INFO_3(DRIVER_INFO_3 *info, PyObject *dict)
-{
- PyObject *dict_copy = PyDict_Copy(dict);
- BOOL result;
-
- PyDict_DelItemString(dict_copy, "level");
- result = to_struct(info, dict_copy, py_DRIVER_INFO_3);
-
- 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));
- 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/source3/python/py_spoolss_forms.c b/source3/python/py_spoolss_forms.c
deleted file mode 100644
index c216e00afe..0000000000
--- a/source3/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, strlen(form_name) + 1);
- 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, 1, &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/source3/python/py_spoolss_jobs.c b/source3/python/py_spoolss_jobs.c
deleted file mode 100644
index cc5d42e0ee..0000000000
--- a/source3/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);
- break;
- case 2:
- py_from_JOB_INFO_2(&result, ctr.job.job_info_2);
- 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/source3/python/py_spoolss_printerdata.c b/source3/python/py_spoolss_printerdata.c
deleted file mode 100644
index e1e43fa736..0000000000
--- a/source3/python/py_spoolss_printerdata.c
+++ /dev/null
@@ -1,234 +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"
-
-static BOOL py_from_printerdata(PyObject **dict, char *value,
- uint32 data_type, char *data,
- uint32 data_size)
-{
- *dict = PyDict_New();
-
- PyDict_SetItemString(*dict, "type", Py_BuildValue("i", data_type));
- PyDict_SetItemString(*dict, "value", Py_BuildValue("s", value));
-
- PyDict_SetItemString(*dict, "data",
- Py_BuildValue("s#", data, data_size));
-
- return True;
-}
-
-static BOOL py_to_printerdata(char **value, uint32 *data_type,
- char **data, uint32 *data_size,
- PyObject *dict)
-{
- PyObject *obj;
-
- 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, "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, "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 *value;
- WERROR werror;
- uint32 needed, data_type, data_size;
- char *data;
- PyObject *result;
-
- /* Parse parameters */
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &value))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_getprinterdata(
- hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, value,
- &data_type, &data, &data_size);
-
- if (W_ERROR_V(werror) == ERRmoredata)
- werror = cli_spoolss_getprinterdata(
- hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol, value,
- &data_type, &data, &data_size);
-
- if (!W_ERROR_IS_OK(werror)) {
- PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
- return NULL;
- }
-
- py_from_printerdata(&result, value, data_type, data, needed);
-
- 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 *value, *data;
- uint32 data_size, data_type;
- WERROR werror;
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kw, "O!", kwlist, &PyDict_Type, &py_data))
- return NULL;
-
- if (!py_to_printerdata(&value, &data_type, &data, &data_size, py_data))
- return NULL;
-
- /* Call rpc function */
-
- werror = cli_spoolss_setprinterdata(
- hnd->cli, hnd->mem_ctx, &hnd->pol, value, data_type,
- data, data_size);
-
- 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, data_size, data_type;
- char *value, *data;
- WERROR werror;
- PyObject *result;
-
- 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, NULL, NULL, 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, &data_type, &data, &data_size);
-
- if (py_from_printerdata(&obj, value, data_type, data,
- data_size))
- PyDict_SetItemString(result, value, 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_deleteprinterdataex(PyObject *self, PyObject *args, PyObject *kw)
-{
- /* Not supported by Samba server */
-
- PyErr_SetString(spoolss_error, "Not implemented");
- return NULL;
-}
diff --git a/source3/python/py_spoolss_printers.c b/source3/python/py_spoolss_printers.c
deleted file mode 100644
index 8d4cd24778..0000000000
--- a/source3/python/py_spoolss_printers.c
+++ /dev/null
@@ -1,480 +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, PIPE_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init())) {
- 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;
-
- if (level < 0 || level > 3) {
- PyErr_SetString(spoolss_error, "Invalid info 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(&pinfo.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(&pinfo.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(&pinfo.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, PIPE_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init())) {
- 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, flags, level,
- &num_printers, &ctr);
-
- if (W_ERROR_V(werror) == ERRinsufficientbuffer)
- werror = cli_spoolss_enum_printers(
- cli, mem_ctx, needed, NULL, 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 name;
-
- rpcstr_pull(name, 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, name, value);
- }
-
- break;
- case 1:
- result = PyDict_New();
-
- for(i = 0; i < num_printers; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, 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, name, value);
- }
-
- break;
- case 2:
- result = PyDict_New();
-
- for(i = 0; i < num_printers; i++) {
- PyObject *value;
- fstring name;
-
- rpcstr_pull(name, 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, 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;
-}
-
-/* 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, PIPE_SPOOLSS, &errstr))) {
- PyErr_SetString(spoolss_error, errstr);
- free(errstr);
- goto done;
- }
-
- if (!(mem_ctx = talloc_init())) {
- 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/source3/python/py_spoolss_printers_conv.c b/source3/python/py_spoolss_printers_conv.c
deleted file mode 100644
index 247db65b1e..0000000000
--- a/source3/python/py_spoolss_printers_conv.c
+++ /dev/null
@@ -1,296 +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;
-
- if (!to_struct(devmode, dict, py_DEVICEMODE))
- return False;
-
- if (!(obj = PyDict_GetItemString(dict, "private")))
- return False;
-
- devmode->private = PyString_AsString(obj);
- devmode->driverextra = PyString_Size(obj);
-
- return True;
-}
-
-/*
- * 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 *dict_copy = PyDict_Copy(dict);
- BOOL result;
-
- PyDict_DelItemString(dict_copy, "level");
- result = to_struct(info, dict_copy, py_PRINTER_INFO_1);
-
- 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);
-
- if (py_from_SECDESC(&obj, info->secdesc))
- PyDict_SetItemString(*dict, "security_descriptor", obj);
-
- if (py_from_DEVICEMODE(&obj, info->devmode))
- 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;
-
- if (!to_struct(info, dict, py_PRINTER_INFO_2))
- return False;
-
- if (!(obj = PyDict_GetItemString(dict, "security_descriptor")))
- return False;
-
- if (!py_to_SECDESC(&info->secdesc, obj, mem_ctx))
- return False;
-
- if (!(obj = PyDict_GetItemString(dict, "device_mode")))
- return False;
-
- info->devmode = talloc(mem_ctx, sizeof(DEVICEMODE));
-
- if (!py_to_DEVICEMODE(info->devmode, obj))
- return False;
-
- return True;
-}
-
-/*
- * 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/source3/python/py_spoolss_proto.h b/source3/python/py_spoolss_proto.h
deleted file mode 100644
index 5b68ef815a..0000000000
--- a/source3/python/py_spoolss_proto.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef _PY_SPOOLSS_PROTO_H
-#define _PY_SPOOLSS_PROTO_H
-
-/* This file is automatically generated with "make proto". DO NOT EDIT */
-
-
-/* The following definitions come from python/py_spoolss.c */
-
-PyObject *new_spoolss_policy_hnd_object(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, POLICY_HND *pol);
-void initspoolss(void);
-
-/* 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_deleteprinterdataex(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_PROTO_H */
diff --git a/source3/python/py_winbind.c b/source3/python/py_winbind.c
deleted file mode 100644
index 49c7f8e924..0000000000
--- a/source3/python/py_winbind.c
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Python wrapper for winbind client functions.
-
- 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 "includes.h"
-#include "Python.h"
-
-#include "py_common_proto.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, *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) {
- 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) {
- 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) {
- 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()));
-
- /* Winbind uid/gid range */
-
- if (lp_winbind_uid(&ulow, &uhi)) {
- PyDict_SetItemString(result, "uid_low", PyInt_FromLong(ulow));
- PyDict_SetItemString(result, "uid_high", PyInt_FromLong(uhi));
- }
-
- if (lp_winbind_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)
-{
- 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_crap.user, username);
-
- generate_random_buffer(request.data.auth_crap.chal, 8, False);
-
- SMBencrypt((uchar *)password, request.data.auth_crap.chal,
- (uchar *)request.data.auth_crap.lm_resp);
- SMBNTencrypt((uchar *)password, request.data.auth_crap.chal,
- (uchar *)request.data.auth_crap.nt_resp);
-
- request.data.auth_crap.lm_resp_len = 24;
- 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);
-}
-
-/*
- * Method dispatch table
- */
-
-static PyMethodDef winbind_methods[] = {
-
- /* Name <-> SID conversion */
-
- { "name_to_sid", py_name_to_sid, METH_VARARGS,
- "name_to_sid(s) -> string
-
-Return the SID for a name.
-
-Example:
-
->>> winbind.name_to_sid('FOO/Administrator')
-'S-1-5-21-406022937-1377575209-526660263-500' " },
-
- { "sid_to_name", py_sid_to_name, METH_VARARGS,
- "sid_to_name(s) -> string
-
-Return the name for a SID.
-
-Example:
-
->>> import winbind
->>> winbind.sid_to_name('S-1-5-21-406022937-1377575209-526660263-500')
-'FOO/Administrator' " },
-
- /* Enumerate users/groups */
-
- { "enum_domain_users", py_enum_domain_users, METH_VARARGS,
- "enum_domain_users() -> list of strings
-
-Return a list of domain users.
-
-Example:
-
->>> winbind.enum_domain_users()
-['FOO/Administrator', 'FOO/anna', 'FOO/Anne Elk', 'FOO/build',
-'FOO/foo', 'FOO/foo2', 'FOO/foo3', 'FOO/Guest', 'FOO/user1',
-'FOO/whoops-ptang'] " },
-
- { "enum_domain_groups", py_enum_domain_groups, METH_VARARGS,
- "enum_domain_groups() -> list of strings
-
-Return a list of domain groups.
-
-Example:
-
->>> winbind.enum_domain_groups()
-['FOO/cows', 'FOO/Domain Admins', 'FOO/Domain Guests',
-'FOO/Domain Users'] " },
-
- /* ID mapping */
-
- { "uid_to_sid", py_uid_to_sid, METH_VARARGS,
- "uid_to_sid(int) -> string
-
-Return the SID for a UNIX uid.
-
-Example:
-
->>> winbind.uid_to_sid(10000)
-'S-1-5-21-406022937-1377575209-526660263-500' " },
-
- { "gid_to_sid", py_gid_to_sid, METH_VARARGS,
- "gid_to_sid(int) -> string
-
-Return the UNIX gid for a SID.
-
-Example:
-
->>> winbind.gid_to_sid(10001)
-'S-1-5-21-406022937-1377575209-526660263-512' " },
-
- { "sid_to_uid", py_sid_to_uid, METH_VARARGS,
- "sid_to_uid(string) -> int
-
-Return the UNIX uid for a SID.
-
-Example:
-
->>> winbind.sid_to_uid('S-1-5-21-406022937-1377575209-526660263-500')
-10000 " },
-
- { "sid_to_gid", py_sid_to_gid, METH_VARARGS,
- "sid_to_gid(string) -> int
-
-Return the UNIX gid corresponding to a SID.
-
-Example:
-
->>> winbind.sid_to_gid('S-1-5-21-406022937-1377575209-526660263-512')
-10001 " },
-
- /* Miscellaneous */
-
- { "check_secret", py_check_secret, METH_VARARGS,
- "check_secret() -> int
-
-Check the machine trust account password. The NT status is returned
-with zero indicating success. " },
-
- { "enum_trust_dom", py_enum_trust_dom, METH_VARARGS,
- "enum_trust_dom() -> list of strings
-
-Return a list of trusted domains. The domain the server is a member
-of is not included.
-
-Example:
-
->>> winbind.enum_trust_dom()
-['NPSD-TEST2', 'SP2NDOM'] " },
-
- /* PAM authorisation functions */
-
- { "auth_plaintext", py_auth_plaintext, METH_VARARGS,
- "auth_plaintext(s, s) -> int
-
-Authenticate a username and password using plaintext authentication.
-The NT status code is returned with zero indicating success." },
-
- { "auth_crap", py_auth_crap, METH_VARARGS,
- "auth_crap(s, s) -> int
-
-Authenticate a username and password using the challenge/response
-protocol. The NT status code is returned with zero indicating
-success." },
-
- { 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/source3/python/samba-head.patch b/source3/python/samba-head.patch
deleted file mode 100644
index a739346a5b..0000000000
--- a/source3/python/samba-head.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-Index: Makefile.in
-===================================================================
-RCS file: /data/cvs/samba/source/Makefile.in,v
-retrieving revision 1.500
-diff -u -r1.500 Makefile.in
---- Makefile.in 2002/07/28 06:04:32 1.500
-+++ Makefile.in 2002/07/29 03:48:03
-@@ -838,6 +838,45 @@
- -$(INSTALLCMD) -d ${prefix}/include
- -$(INSTALLCMD) include/libsmbclient.h ${prefix}/include
-
-+# Python extensions
-+
-+PYTHON_OBJS = $(LIB_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) $(UBIQX_OBJ) \
-+ $(PARAM_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ)
-+
-+PY_SPOOLSS_PROTO_OBJ = python/py_spoolss.o \
-+ python/py_spoolss_printers.o python/py_spoolss_printers_conv.o\
-+ python/py_spoolss_forms.o python/py_spoolss_forms_conv.o \
-+ python/py_spoolss_ports.o python/py_spoolss_ports_conv.o \
-+ python/py_spoolss_drivers.o python/py_spoolss_drivers_conv.o \
-+ python/py_spoolss_jobs.o python/py_spoolss_jobs_conv.o \
-+ python/py_spoolss_printerdata.o
-+
-+PY_LSA_PROTO_OBJ = python/py_lsa.o
-+
-+PY_COMMON_PROTO_OBJ = python/py_common.c python/py_ntsec.c
-+
-+python_proto: python_spoolss_proto python_lsa_proto python_common_proto
-+
-+python_spoolss_proto:
-+ @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
-+ -h _PY_SPOOLSS_PROTO_H python/py_spoolss_proto.h \
-+ $(PY_SPOOLSS_PROTO_OBJ)
-+
-+python_lsa_proto:
-+ @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
-+ -h _PY_LSA_PROTO_H python/py_lsa_proto.h \
-+ $(PY_LSA_PROTO_OBJ)
-+
-+python_common_proto:
-+ @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
-+ -h _PY_COMMON_PROTO_H python/py_common_proto.h \
-+ $(PY_COMMON_PROTO_OBJ)
-+
-+python_ext: $(PYTHON_OBJS)
-+ @echo python python/setup.py build
-+ @PYTHON_OBJS="$(PYTHON_OBJS)" PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS)" \
-+ python python/setup.py build
-+
- # revert to the previously installed version
- revert:
- @$(SHELL) $(srcdir)/script/revert.sh $(SBINDIR) $(SPROGS)
-Index: configure.in
-===================================================================
-RCS file: /data/cvs/samba/source/configure.in,v
-retrieving revision 1.324
-diff -u -r1.324 configure.in
---- configure.in 2002/07/27 01:37:32 1.324
-+++ configure.in 2002/07/29 03:48:04
-@@ -2797,7 +2797,7 @@
- builddir=`pwd`
- AC_SUBST(builddir)
-
--AC_OUTPUT(include/stamp-h Makefile script/findsmb)
-+AC_OUTPUT(include/stamp-h Makefile script/findsmb python/setup.py)
-
- #################################################
- # Print very concise instructions on building/use
diff --git a/source3/python/setup.py.in b/source3/python/setup.py.in
deleted file mode 100755
index c61ec2c214..0000000000
--- a/source3/python/setup.py.in
+++ /dev/null
@@ -1,163 +0,0 @@
-# -*- mode: python -*-
-#
-# Unix SMB/CIFS implementation.
-# Module packaging setup for Samba python extensions
-#
-# 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.
-#
-
-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 = ""
-if os.environ.has_key("PYTHON_OBJS"):
- samba_objs = os.environ.get("PYTHON_OBJS")
-
-samba_cflags = ""
-if os.environ.has_key("PYTHON_CFLAGS"):
- samba_cflags = os.environ.get("PYTHON_CFLAGS")
-
-samba_srcdir = ""
-if os.environ.has_key("SRCDIR"):
- samba_srcdir = os.environ.get("SRCDIR")
-
-# These variables are filled in by configure
-
-samba_libs = "@LIBS@"
-
-# Convert libs and objs from space separated strings to lists of strings
-# for distutils to digest. Split "-l" prefix off library list.
-
-obj_list = string.split(samba_objs)
-
-lib_list = []
-
-for lib in string.split(samba_libs):
- lib_list.append(string.replace(lib, "-l", ""))
-
-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",
-
- # Build info
-
- include_dirs = [samba_srcdir + '.', samba_srcdir + "include",
- samba_srcdir + "ubiqx", samba_srcdir + "smbwrapper",
- samba_srcdir + "popt", "/usr/kerberos/include",
- "/usr/local/include"],
-
- # Module list
-
- 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_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 = lib_list,
- library_dirs = ["/usr/kerberos/lib"],
- 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 = lib_list,
- library_dirs = ["/usr/kerberos/lib"],
- extra_objects = obj_list),
-
- # SAMR pipe module
-
- Extension(name = "samr",
- sources = [samba_srcdir + "python/py_samr.c",
- samba_srcdir + "python/py_common.c"],
- libraries = lib_list,
- library_dirs = ["/usr/kerberos/lib"],
- extra_objects = obj_list),
-
- # winbind client module
-
- Extension(name = "winbind",
- sources = [samba_srcdir + "python/py_winbind.c",
- samba_srcdir + "python/py_common.c"],
- libraries = lib_list,
- library_dirs = ["/usr/kerberos/lib"],
- extra_objects = obj_list,
- extra_compile_args = flags_list),
-
- # WINREG pipe module
-
- Extension(name = "winreg",
- sources = [samba_srcdir + "python/py_winreg.c",
- samba_srcdir + "python/py_common.c"],
- libraries = lib_list,
- library_dirs = ["/usr/kerberos/lib"],
- extra_objects = obj_list),
-
- # tdb module
-
- Extension(name = "tdb",
- sources = [samba_srcdir + "python/py_tdb.c"],
- libraries = lib_list,
- library_dirs = ["/usr/kerberos/lib"],
- extra_objects = obj_list),
-
- # libsmb module
-
- Extension(name = "smb",
- sources = [samba_srcdir + "python/py_smb.c",
- samba_srcdir + "python/py_common.c"],
- libraries = lib_list,
- library_dirs = ["/usr/kerberos/lib"],
- extra_objects = obj_list),
-
- ],
-)
diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c
new file mode 100644
index 0000000000..7b5bf90c5d
--- /dev/null
+++ b/source3/rpc_client/cli_login.c
@@ -0,0 +1,173 @@
+/*
+ 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) 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, (char *)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;
+}
+
+/****************************************************************************
+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 *domain, char *username,
+ uint32 smb_userid_low, char *password,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
+{
+ uchar lm_owf_user_pwd[16];
+ uchar nt_owf_user_pwd[16];
+ NTSTATUS ret;
+
+ DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
+
+ nt_lm_owf_gen(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, domain, 0,
+ smb_userid_low, 0,
+ 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,
+ const auth_usersupplied_info *user_info,
+ uchar chal[8],
+ uint32 smb_userid_low, NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3)
+{
+ DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
+ /* indicate a "network" login */
+ ctr->switch_value = NET_LOGON_TYPE;
+
+ /* Create the structure needed for SAM logon. */
+ init_id_info2(&ctr->auth.id2, user_info->domain.str, 0, smb_userid_low, 0,
+ user_info->smb_name.str,
+ /* Send our cleint's workstaion name if we have it, otherwise ours */
+ ((user_info->wksta_name.len > 0) ?
+ user_info->wksta_name.str :
+ cli->clnt_name_slash),
+ chal,
+ user_info->lm_resp.data, user_info->lm_resp.length,
+ user_info->nt_resp.data, user_info->nt_resp.length);
+
+ /* 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/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index acc9135542..90c8a34c21 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -1,258 +1,34 @@
/*
- 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"
-
-/* LSA Request Challenge. Sends our challenge to server, then gets
- server response. These are used to generate the credentials. */
-
-NTSTATUS 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,("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;
-}
-
-/****************************************************************************
-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_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,("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;
- }
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Initialize domain session credentials */
-
-NTSTATUS 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 = 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 ********************/
-
- /* 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, sec_chan, 0x000001ff, &srv_chal);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n",
- nt_errstr(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;
- }
+ * 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 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.
+ */
- result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+#include "includes.h"
- return result;
-}
+extern pstring global_myname;
+extern fstring global_myworkgroup;
/****************************************************************************
-Generate the next creds to use. Yuck - this is a cut&paste from another
-file. They should be combined at some stage. )-:
+Generate the next creds to use.
****************************************************************************/
static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
@@ -271,394 +47,424 @@ static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
}
-/* 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)
+#if UNUSED_CODE
+/****************************************************************************
+do a LSA Logon Control2
+****************************************************************************/
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, NTSTATUS status_level)
{
- 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;
+ 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, 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", nt_errstr(r_l.status)));
+ cli->nt_error = r_l.status;
+ ok = False;
+ }
+ }
+
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+
+ return ok;
+}
+#endif
- memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
+/****************************************************************************
+LSA Authenticate 2
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+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.
+****************************************************************************/
- return result;
+NTSTATUS cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
+ uint32 neg_flags, DOM_CHAL *srv_chal)
+{
+ 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, 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", nt_errstr(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 ));
+ 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;
}
-/* Sam synchronisation */
+/****************************************************************************
+LSA Request Challenge. Sends our challenge to server, then gets
+server response. These are used to generate the credentials.
+****************************************************************************/
-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)
+BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
{
- 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;
+ 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, 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", nt_errstr(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;
}
+/***************************************************************************
+ LSA SAM Logon internal - interactive or network. Does level 2 or 3 but always
+ returns level 3.
+****************************************************************************/
-/* Logon domain user */
-
-NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- char *username, char *password,
- int logon_type)
+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_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;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
+ 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;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ gen_next_creds( cli, &new_clnt_cred);
- /* Initialise input parameters */
+ prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
- gen_next_creds(cli, &clnt_creds);
+ /* create and send a MSRPC command with api NET_SAMLOGON */
- q.validation_level = validation_level;
+ 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));
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(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,
- 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, &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 */
+ /* store the parameters */
+ q_s.validation_level = validation_level;
+ init_sam_info(&q_s.sam_id, cli->srv_name_slash,
+ global_myname, &new_clnt_cred, &dummy_rtn_creds,
+ ctr->switch_value, ctr);
- r.user = &user;
-
- if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
- 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;
}
- /* Return results */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
+ /* 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;
+ }
-/**
- * Logon domain user with an 'network' SAM logon
- *
- * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
- **/
+ r_s.user = user_info3;
-NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- 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)
+ 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;
-{
- 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;
+ /*
+ * Don't treat NT_STATUS_INVALID_INFO_CLASS as an error - we will re-issue
+ * the call.
+ */
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ if (NT_STATUS_V(retval) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
+ goto out;
+ }
- workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
-
- if (!workstation_name_slash) {
- DEBUG(0, ("talloc_asprintf failed!\n"));
- return NT_STATUS_NO_MEMORY;
+ if (!NT_STATUS_IS_OK(retval)) {
+ /* report error code */
+ DEBUG(0,("cli_net_sam_logon_internal: %s\n", nt_errstr(r_s.status)));
+ goto out;
}
- /* Initialise parse structures */
+ /* 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;
+ }
+
+ 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;
+ }
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+out:
- /* Initialise input parameters */
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+
+ return retval;
+}
- gen_next_creds(cli, &clnt_creds);
+/***************************************************************************
+LSA SAM Logon - interactive or network.
+****************************************************************************/
- q.validation_level = validation_level;
+NTSTATUS cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3)
+{
+ uint16 validation_level=3;
+ NTSTATUS result;
- memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
- dummy_rtn_creds.timestamp.time = time(NULL);
+ result = cli_net_sam_logon_internal(cli, ctr, user_info3,
+ validation_level);
- ctr.switch_value = NET_LOGON_TYPE;
+ 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"));
- 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, &dummy_rtn_creds, NET_LOGON_TYPE,
- &ctr);
+ validation_level=2;
- /* Marshall data and send request */
+ /*
+ * Since this is the second time we call this function, don't care
+ * for the error. If its error, return False.
+ */
- if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
- goto done;
+ result = cli_net_sam_logon_internal(cli, ctr, user_info3,
+ validation_level);
}
- /* Unmarshall response */
+ return result;
+}
- r.user = info3;
+/***************************************************************************
+LSA SAM Logoff.
- if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
- goto done;
- }
+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)
+{
+ 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;
- /* Return results */
+ gen_next_creds( cli, &new_clnt_cred);
- result = r.status;
+ prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ /* create and send a MSRPC command with api NET_SAMLOGOFF */
- return result;
-}
+ 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));
-/***************************************************************************
-LSA Server Password Set.
-****************************************************************************/
+ memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
-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;
+ init_sam_info(&q_s.sam_id, cli->srv_name_slash,
+ global_myname, &new_clnt_cred, &dummy_rtn_creds,
+ ctr->switch_value, ctr);
- 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;
- }
+ /* 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;
+ }
- 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;
- }
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, NET_SAMLOGOFF, &buf, &rbuf))
+ {
+ NET_R_SAM_LOGOFF r_s;
+
+ 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", nt_errstr(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/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c
index aaf18882f7..07001f13bd 100644
--- a/source3/rpc_client/cli_reg.c
+++ b/source3/rpc_client/cli_reg.c
@@ -1,102 +1,1074 @@
/*
- 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
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the 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-1998,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the 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 */
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
-NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
- const char *msg, uint32 timeout, uint16 flags)
+/****************************************************************************
+do a REG Open Policy
+****************************************************************************/
+BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name,
+ POLICY_HND *reg_hnd)
{
- prs_struct qbuf;
- prs_struct rbuf;
- REG_Q_SHUTDOWN q_s;
- REG_R_SHUTDOWN r_s;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- if (msg == NULL) return NT_STATUS_INVALID_PARAMETER;
+ BOOL res = True;
+ uint32 reg_type = 0;
- ZERO_STRUCT (q_s);
- ZERO_STRUCT (r_s);
+ if (full_keyname == NULL)
+ return False;
- prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ ZERO_STRUCTP(reg_hnd);
- /* Marshall data and send request */
+ /*
+ * open registry receive a policy handle
+ */
- init_reg_q_shutdown(&q_s, msg, timeout, flags);
+ if (!reg_split_key(full_keyname, &reg_type, key_name)) {
+ DEBUG(0,("do_reg_connect: unrecognised key name %s\n", full_keyname));
+ return False;
+ }
- if (!reg_io_q_shutdown("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, REG_SHUTDOWN, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
+ switch (reg_type) {
+ case HKEY_LOCAL_MACHINE:
+ res = res ? do_reg_open_hklm(cli, 0x84E0, 0x02000000, reg_hnd) : False;
+ break;
- if(reg_io_r_shutdown("", &r_s, &rbuf, 0))
- result = r_s.status;
+ case HKEY_USERS:
+ res = res ? do_reg_open_hku(cli, 0x84E0, 0x02000000, reg_hnd) : False;
+ break;
+
+ default:
+ DEBUG(0,("do_reg_connect: unrecognised hive key\n"));
+ return False;
+ }
+
+ return res;
+}
+
+/****************************************************************************
+do a REG Open Policy
+****************************************************************************/
+BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_OPEN_HKLM q_o;
+ REG_R_OPEN_HKLM r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_OPEN_HKLM */
+
+ DEBUG(4,("REG Open HKLM\n"));
+
+ init_reg_q_open_hklm(&q_o, unknown_0, level);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_open_hklm("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_OPEN_HKLM, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_open_hklm("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_HKLM: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Open HKU
+****************************************************************************/
+BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_OPEN_HKU q_o;
+ REG_R_OPEN_HKU r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_OPEN_HKU */
+
+ DEBUG(4,("REG Open HKU\n"));
+
+ init_reg_q_open_hku(&q_o, unknown_0, level);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_open_hku("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_OPEN_HKU, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_open_hku("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_HKU: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
-done:
prs_mem_free(&rbuf);
- prs_mem_free(&qbuf);
- return result;
+ return True;
}
+/****************************************************************************
+do a REG Unknown 0xB command. sent after a create key or create value.
+this might be some sort of "sync" or "refresh" command, sent after
+modification of the registry...
+****************************************************************************/
+BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_FLUSH_KEY q_o;
+ REG_R_FLUSH_KEY r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_FLUSH_KEY */
+
+ DEBUG(4,("REG Unknown 0xB\n"));
+
+ init_reg_q_flush_key(&q_o, hnd);
-/* Abort a server shutdown */
+ /* turn parameters into data stream */
+ if(!reg_io_q_flush_key("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_FLUSH_KEY, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_flush_key("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_FLUSH_KEY: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
-NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
+/****************************************************************************
+do a REG Query Key
+****************************************************************************/
+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)
{
prs_struct rbuf;
- prs_struct qbuf;
- REG_Q_ABORT_SHUTDOWN q_s;
- REG_R_ABORT_SHUTDOWN r_s;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ prs_struct buf;
+ REG_Q_QUERY_KEY q_o;
+ REG_R_QUERY_KEY r_o;
- ZERO_STRUCT (q_s);
- ZERO_STRUCT (r_s);
+ if (hnd == NULL)
+ return False;
- prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
- init_reg_q_abort_shutdown(&q_s);
+ /* create and send a MSRPC command with api REG_QUERY_KEY */
- if (!reg_io_q_abort_shutdown("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, REG_ABORT_SHUTDOWN, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0))
- result = r_s.status;
+ DEBUG(4,("REG Query Key\n"));
+
+ init_reg_q_query_key(&q_o, hnd, *class_len);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_query_key("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_query_key("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_QUERY_KEY: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ *class_len = r_o.hdr_class.uni_max_len;
+ rpcstr_pull(class, &r_o.uni_class, -1, -1, 0);
+ *num_subkeys = r_o.num_subkeys ;
+ *max_subkeylen = r_o.max_subkeylen ;
+ *max_subkeysize = r_o.max_subkeysize;
+ *num_values = r_o.num_values ;
+ *max_valnamelen = r_o.max_valnamelen;
+ *max_valbufsize = r_o.max_valbufsize;
+ *sec_desc = r_o.sec_desc ;
+ *mod_time = r_o.mod_time ;
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Unknown 1A
+****************************************************************************/
+BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_UNK_1A q_o;
+ REG_R_UNK_1A r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_UNKNOWN_1A */
+
+ DEBUG(4,("REG Unknown 1a\n"));
+
+ init_reg_q_unk_1a(&q_o, hnd);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_unk_1a("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_UNK_1A, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_unk_1a("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_UNK_1A: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ (*unk) = r_o.unknown;
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Query Info
+****************************************************************************/
+BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
+ char *key_value, uint32* key_type)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_INFO q_o;
+ REG_R_INFO r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_INFO */
+
+ DEBUG(4,("REG Query Info\n"));
+
+ init_reg_q_info(&q_o, hnd, "ProductType");
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_info("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_INFO, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_info("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if ( r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_INFO: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /*fstrcpy(key_value, dos_buffer2_to_str(r_o.uni_val));*/
+ rpcstr_pull(key_value, r_o.uni_val->buffer, sizeof(fstring), r_o.uni_val->buf_len, 0);
+ *key_type = r_o.type;
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Set Key Security
+****************************************************************************/
+BOOL do_reg_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_SET_KEY_SEC q_o;
+ REG_R_SET_KEY_SEC r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_SET_KEY_SEC */
+
+ DEBUG(4,("REG Set Key security.\n"));
+
+ init_reg_q_set_key_sec(&q_o, hnd, sec_desc_buf);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_set_key_sec("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_SET_KEY_SEC, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_set_key_sec("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Query Key Security
+****************************************************************************/
+
+BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_GET_KEY_SEC q_o;
+ REG_R_GET_KEY_SEC r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_GET_KEY_SEC */
+
+ DEBUG(4,("REG query key security. buf_size: %d\n", *sec_buf_size));
+
+ init_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, NULL);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_get_key_sec("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_GET_KEY_SEC, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_get_key_sec("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status == 0x0000007a) {
+ /*
+ * get the maximum buffer size: it was too small
+ */
+ (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
+ DEBUG(5,("sec_buf_size too small. use %d\n", *sec_buf_size));
+ } else if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_GET_KEY_SEC: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ } else {
+ (*sec_buf_size) = r_o.data->len;
+ *ppsec_desc_buf = r_o.data;
+ }
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Delete Value
+****************************************************************************/
+BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_DELETE_VALUE q_o;
+ REG_R_DELETE_VALUE r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_DELETE_VALUE */
+
+ DEBUG(4,("REG Delete Value: %s\n", val_name));
+
+ init_reg_q_delete_val(&q_o, hnd, val_name);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_delete_val("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_DELETE_VALUE, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_delete_val("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_DELETE_VALUE: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Delete Key
+****************************************************************************/
+BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_DELETE_KEY q_o;
+ REG_R_DELETE_KEY r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_DELETE_KEY */
+
+ DEBUG(4,("REG Delete Key: %s\n", key_name));
+
+ init_reg_q_delete_key(&q_o, hnd, key_name);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_delete_key("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_DELETE_KEY, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_delete_key("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_DELETE_KEY: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Create Key
+****************************************************************************/
+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)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_CREATE_KEY q_o;
+ REG_R_CREATE_KEY r_o;
+ SEC_DESC *sec = NULL;
+ SEC_DESC_BUF *sec_buf = NULL;
+ size_t sec_len;
+
+ ZERO_STRUCT(q_o);
+
+ if (hnd == NULL)
+ return False;
+
+ /* create and send a MSRPC command with api REG_CREATE_KEY */
+
+ DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class,
+ sam_access != NULL ? sam_access->mask : 0));
+
+ if((sec = make_sec_desc( cli->mem_ctx, 1, NULL, NULL, NULL, NULL, &sec_len)) == NULL) {
+ DEBUG(0,("make_sec_desc : malloc fail.\n"));
+ return False;
+ }
+
+ DEBUG(10,("make_sec_desc: len = %d\n", (int)sec_len));
+
+ if((sec_buf = make_sec_desc_buf( cli->mem_ctx, (int)sec_len, sec)) == NULL) {
+ DEBUG(0,("make_sec_desc : malloc fail (1)\n"));
+ return False;
+ }
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ init_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access, sec_buf);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_create_key("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_CREATE_KEY, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_create_key("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_CREATE_KEY: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ *key = r_o.key_pol;
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Enum 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)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_ENUM_KEY q_o;
+ REG_R_ENUM_KEY r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_ENUM_KEY */
+
+ DEBUG(4,("REG Enum Key\n"));
+
+ init_reg_q_enum_key(&q_o, hnd, key_index);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_enum_key("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_ENUM_KEY, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_enum_key("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_ENUM_KEY: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ (*unk_1) = r_o.unknown_1;
+ (*unk_2) = r_o.unknown_2;
+ rpcstr_pull(key_name, r_o.key_name.str.buffer, -1, -1, 0);
+ (*mod_time) = nt_time_to_unix(&r_o.time);
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Create Value
+****************************************************************************/
+BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
+ char *val_name, uint32 type, BUFFER3 *data)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_CREATE_VALUE q_o;
+ REG_R_CREATE_VALUE r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_CREATE_VALUE */
+
+ DEBUG(4,("REG Create Value: %s\n", val_name));
+
+ init_reg_q_create_val(&q_o, hnd, val_name, type, data);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_create_val("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_CREATE_VALUE, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_create_val("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_CREATE_VALUE: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Enum Value
+****************************************************************************/
+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)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_ENUM_VALUE q_o;
+ REG_R_ENUM_VALUE r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_ENUM_VALUE */
+
+ DEBUG(4,("REG Enum Value\n"));
+
+ init_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_enum_val("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_ENUM_VALUE, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+ r_o.buf_value = value;
+
+ if(!reg_io_r_enum_val("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_ENUM_VALUE: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ (*val_type) = r_o.type;
+ rpcstr_pull(val_name, &r_o.uni_name, -1, -1, 0);
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Open Key
+****************************************************************************/
+BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
+ char *key_name, uint32 unk_0,
+ POLICY_HND *key_hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_OPEN_ENTRY q_o;
+ REG_R_OPEN_ENTRY r_o;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api REG_OPEN_ENTRY */
+
+ DEBUG(4,("REG Open Entry\n"));
+
+ init_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_open_entry("", &q_o, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_OPEN_ENTRY, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_o);
+
+ if(!reg_io_r_open_entry("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_ENTRY: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ *key_hnd = r_o.pol;
+
+ prs_mem_free(&rbuf);
+
+ return True;
+}
+
+/****************************************************************************
+do a REG Close
+****************************************************************************/
+BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_CLOSE q_c;
+ REG_R_CLOSE r_c;
+
+ if (hnd == NULL)
+ return False;
+
+ /* create and send a MSRPC command with api REG_CLOSE */
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
+
+ DEBUG(4,("REG Close\n"));
+
+ /* store the parameters */
+ init_reg_q_close(&q_c, hnd);
+
+ /* turn parameters into data stream */
+ if(!reg_io_q_close("", &q_c, &buf, 0)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, REG_CLOSE, &buf, &rbuf)) {
+ prs_mem_free(&buf);
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ prs_mem_free(&buf);
+
+ ZERO_STRUCT(r_c);
+
+ if(!reg_io_r_close("", &r_c, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ if (r_c.status != 0) {
+ /* report error code */
+ DEBUG(0,("REG_CLOSE: %s\n", nt_errstr(r_c.status)));
+ prs_mem_free(&rbuf);
+ return False;
+ }
+
+ /* check that the returned policy handle is all zeros */
+
+ if (IVAL(&r_c.pol.data1,0) || IVAL(&r_c.pol.data2,0) || SVAL(&r_c.pol.data3,0) ||
+ SVAL(&r_c.pol.data4,0) || IVAL(r_c.pol.data5,0) || IVAL(r_c.pol.data5,4) ) {
+ prs_mem_free(&rbuf);
+ DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
+ return False;
+ }
-done:
prs_mem_free(&rbuf);
- prs_mem_free(&qbuf );
- return result;
+ return True;
}
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index 7863d32419..0d4db7f88f 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -1,12 +1,9 @@
/*
Unix SMB/CIFS implementation.
- RPC pipe client
- Copyright (C) Tim Potter 2000-2001,
- 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.
+ 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
@@ -25,1427 +22,819 @@
#include "includes.h"
-/* Connect to SAMR database */
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
-NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 access_mask, POLICY_HND *connect_pol)
+/****************************************************************************
+do a SAMR query user groups
+****************************************************************************/
+BOOL get_samr_query_usergroups(struct cli_state *cli,
+ POLICY_HND *pol_open_domain, uint32 user_rid,
+ uint32 *num_groups, DOM_GID *gid)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_CONNECT q;
- SAMR_R_CONNECT r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ POLICY_HND pol_open_user;
+ if (pol_open_domain == NULL || num_groups == NULL || gid == NULL)
+ return 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_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))
- 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
+ /* send open domain (on user sid) */
+ if (!do_samr_open_user(cli,
+ pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
}
- 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;
-
- 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))
- 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
+ /* send user groups query */
+ if (!do_samr_query_usergroups(cli,
+ &pol_open_user,
+ num_groups, gid))
+ {
+ DEBUG(5,("do_samr_query_usergroups: error in query user groups\n"));
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ return do_samr_close(cli, &pol_open_user);
}
-/* Close SAMR handle */
+#if 0
+/* DOES NOT COMPILE WITH THE NEW SAMR PARSE CODE. JRA. */
-NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *connect_pol)
+/****************************************************************************
+do a SAMR query user info
+****************************************************************************/
+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)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_CLOSE_HND q;
- SAMR_R_CLOSE_HND 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);
-
- /* Marshall data and send request */
-
- 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))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
- goto done;
+ POLICY_HND pol_open_user;
+ if (pol_open_domain == NULL || usr == NULL)
+ return False;
- /* Return output parameters */
+ memset((char *)usr, '\0', sizeof(*usr));
- if (NT_STATUS_IS_OK(result = r.status)) {
-#ifdef __INSURE__
- SAFE_FREE(connect_pol->marker);
-#endif
- *connect_pol = r.pol;
+ /* send open domain (on user sid) */
+ if (!do_samr_open_user(cli,
+ pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Open handle on a domain */
-
-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)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_OPEN_DOMAIN q;
- SAMR_R_OPEN_DOMAIN 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);
-
- /* Marshall data and send request */
-
- 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))
- goto done;
-
- /* Unmarshall response */
-
- 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
+ /* send user info query */
+ if (!do_samr_query_userinfo(cli,
+ &pol_open_user,
+ info_level, (void*)usr))
+ {
+ DEBUG(5,("do_samr_query_userinfo: error in query user info, level 0x%x\n",
+ info_level));
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ return do_samr_close(cli, &pol_open_user);
}
-
-/* Open handle on a user */
-
-NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 user_rid, POLICY_HND *user_pol)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_OPEN_USER q;
- SAMR_R_OPEN_USER 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);
-
- /* Marshall data and send request */
-
- 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))
- goto done;
-
- /* Unmarshall response */
-
- 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:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Open handle on a group */
-NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 group_rid, POLICY_HND *group_pol)
+/****************************************************************************
+do a SAMR change user password command
+****************************************************************************/
+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])
{
- prs_struct qbuf, rbuf;
- SAMR_Q_OPEN_GROUP q;
- SAMR_R_OPEN_GROUP 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);
-
- /* Marshall data and send request */
-
- init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_CHGPASSWD_USER q_e;
+ SAMR_R_CHGPASSWD_USER r_e;
- if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf))
- goto done;
+ /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
- /* Unmarshall response */
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- if (!samr_io_r_open_group("", &r, &rbuf, 0))
- goto done;
+ DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
+ srv_name, user_name));
- /* Return output parameters */
+ init_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
+ nt_newpass, nt_oldhash,
+ lm_newpass, lm_oldhash);
- if (NT_STATUS_IS_OK(result = r.status)) {
- *group_pol = r.pol;
-#ifdef __INSURE__
- group_pol->marker = malloc(1);
-#endif
+ /* turn parameters into data stream */
+ if(!samr_io_q_chgpasswd_user("", &q_e, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- 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,
- POLICY_HND *user_pol, uint16 switch_value,
- SAM_USERINFO_CTR **ctr)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_USERINFO q;
- SAMR_R_QUERY_USERINFO 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);
-
- /* Marshall data and send request */
-
- 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))
- goto done;
-
- /* Unmarshall response */
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
- goto done;
+ prs_mem_free(&data);
- /* Return output parameters */
+ if(!samr_io_r_chgpasswd_user("", &r_e, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
+ }
- result = r.status;
- *ctr = r.ctr;
+ if (r_e.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", nt_errstr(r_e.status)));
+ prs_mem_free(&rdata);
+ return False;
+ }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
-/* Query group info */
-
-NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 info_level,
- GROUP_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_GROUPINFO q;
- SAMR_R_QUERY_GROUPINFO 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);
-
- /* Marshall data and send request */
+#if 0
- init_samr_q_query_groupinfo(&q, group_pol, info_level);
+/* CURRENTLY THIS DOESN'T COMPILE AND IS NOT USED ANYWHERE. JRA. */
- if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- r.ctr = ctr;
-
- if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Query user groups */
-
-NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint32 *num_groups,
- DOM_GID **gid)
+/****************************************************************************
+do a SAMR unknown 0x38 command
+****************************************************************************/
+BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_USERGROUPS q;
- SAMR_R_QUERY_USERGROUPS 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);
-
- /* Marshall data and send request */
+ prs_struct data;
+ prs_struct rdata;
- init_samr_q_query_usergroups(&q, user_pol);
+ SAMR_Q_UNKNOWN_38 q_e;
+ SAMR_R_UNKNOWN_38 r_e;
- if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
- goto done;
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
- /* Unmarshall response */
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
- goto done;
+ DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
- /* Return output parameters */
+ init_samr_q_unknown_38(&q_e, srv_name);
- if (NT_STATUS_IS_OK(result = r.status)) {
- *num_groups = r.num_entries;
- *gid = r.gid;
+ /* turn parameters into data stream */
+ if(!samr_io_q_unknown_38("", &q_e, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- 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,
- POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
- uint32 *num_aliases, uint32 **als_rids)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_USERALIASES q;
- SAMR_R_QUERY_USERALIASES r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- unsigned int ptr=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);
-
- /* Marshall data and send request */
-
- 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))
- goto done;
-
- /* Unmarshall response */
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_38, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
- goto done;
+ prs_mem_free(&data);
- /* Return output parameters */
+ if(!samr_io_r_unknown_38("", &r_e, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
+ }
- if (NT_STATUS_IS_OK(result = r.status)) {
- *num_aliases = r.num_entries;
- *als_rids = r.rid;
+ if (r_e.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", nt_errstr(r_e.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
+#endif
-/* Query user groups */
-
-NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 *num_mem,
- uint32 **rid, uint32 **attr)
+/****************************************************************************
+do a SAMR unknown 0x8 command
+****************************************************************************/
+BOOL do_samr_query_dom_info(struct cli_state *cli,
+ POLICY_HND *domain_pol, uint16 switch_value)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_GROUPMEM q;
- SAMR_R_QUERY_GROUPMEM 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);
-
- /* Marshall data and send request */
-
- 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))
- goto done;
-
- /* Unmarshall response */
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_QUERY_DOMAIN_INFO q_e;
+ SAMR_R_QUERY_DOMAIN_INFO r_e;
- if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
- goto done;
+ if (domain_pol == NULL)
+ return False;
- /* Return output parameters */
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
- if (NT_STATUS_IS_OK(result = r.status)) {
- *num_mem = r.num_entries;
- *rid = r.rid;
- *attr = r.attr;
- }
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
- return result;
-}
+ /* store the parameters */
+ init_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
-/**
- * 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 qdata;
- prs_struct rdata;
- SAMR_Q_ENUM_DOM_USERS q;
- SAMR_R_ENUM_DOM_USERS r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- int i;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- if (cli == NULL || pol == NULL)
- return result;
-
- /* initialise parse structures */
- prs_init(&qdata, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rdata, 0, mem_ctx, UNMARSHALL);
-
- DEBUG(4, ("SAMR Enum Domain Users. start_idx: %d, acb: %d, size: %d\n",
- *start_idx, acb_mask, size));
-
- /* fill query structure with parameters */
- init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
-
- /* prepare query stream */
- if (!samr_io_q_enum_dom_users("", &q, &qdata, 0)) {
- prs_mem_free(&qdata);
- prs_mem_free(&rdata);
- return result;
- }
-
- /* send rpc call over the pipe */
- if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qdata, &rdata)) {
- prs_mem_free(&qdata);
+ /* turn parameters into data stream */
+ if(!samr_io_q_query_dom_info("", &q_e, &data, 0)) {
+ prs_mem_free(&data);
prs_mem_free(&rdata);
- return result;
+ return False;
}
-
- /* unpack received stream */
- if(!samr_io_r_enum_dom_users("", &r, &rdata, 0)) {
- prs_mem_free(&qdata);
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &data, &rdata)) {
+ prs_mem_free(&data);
prs_mem_free(&rdata);
- result = r.status;
- return result;
+ return False;
}
-
- /* return the data obtained in response */
- if (!NT_STATUS_IS_OK(r.status) &&
- (NT_STATUS_EQUAL(r.status, STATUS_MORE_ENTRIES) ||
- NT_STATUS_EQUAL(r.status, NT_STATUS_NO_MORE_ENTRIES))) {
- return r.status;
- }
-
- *start_idx = r.next_idx;
- *num_dom_users = r.num_entries2;
- result = r.status;
-
- 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);
- }
- }
-
- prs_mem_free(&qdata);
- prs_mem_free(&rdata);
-
- return result;
-};
-
-
-/* Enumerate domain groups */
-
-NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *start_idx,
- uint32 size, struct acct_info **dom_groups,
- uint32 *num_dom_groups)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_ENUM_DOM_GROUPS q;
- SAMR_R_ENUM_DOM_GROUPS r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 name_idx, 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_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
+ prs_mem_free(&data);
- if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
- !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))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (!NT_STATUS_IS_OK(result) &&
- NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
- goto done;
-
- *num_dom_groups = r.num_entries2;
-
- if (!((*dom_groups) = (struct acct_info *)
- talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ if(!samr_io_r_query_dom_info("", &r_e, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
- memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
-
- name_idx = 0;
-
- for (i = 0; i < *num_dom_groups; i++) {
-
- (*dom_groups)[i].rid = r.sam[i].rid;
-
- if (r.sam[i].hdr_name.buffer) {
- unistr2_to_ascii((*dom_groups)[i].acct_name,
- &r.uni_grp_name[name_idx],
- sizeof(fstring) - 1);
- name_idx++;
- }
-
- *start_idx = r.next_idx;
+ if (r_e.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", nt_errstr(r_e.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
-/* Enumerate domain groups */
+#if 0
-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_groups,
- uint32 *num_dom_groups)
+/* CURRENTLY DOESN'T COMPILE WITH THE NEW SAMR PARSE CODE. JRA */
+
+/****************************************************************************
+do a SAMR enumerate users
+****************************************************************************/
+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)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_ENUM_DOM_ALIASES q;
- SAMR_R_ENUM_DOM_ALIASES r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 name_idx, i;
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_ENUM_DOM_USERS q_e;
+ SAMR_R_ENUM_DOM_USERS r_e;
+ int i;
+ int name_idx = 0;
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ if (pol == NULL || num_sam_users == NULL)
+ return False;
- /* Initialise parse structures */
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- /* Marshall data and send request */
+ DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
- init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
+ /* store the parameters */
+ init_samr_q_enum_dom_users(&q_e, pol,
+ num_entries, unk_0,
+ acb_mask, unk_1, size);
- if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
- goto done;
+ /* turn parameters into data stream */
+ if(!samr_io_q_enum_dom_users("", &q_e, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Unmarshall response */
-
- if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
- goto done;
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
+ prs_mem_free(&data);
- result = r.status;
-
- if (!NT_STATUS_IS_OK(result) &&
- NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
- goto done;
+ if(!samr_io_r_enum_dom_users("", &r_e, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
- *num_dom_groups = r.num_entries2;
-
- if (!((*dom_groups) = (struct acct_info *)
- talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ if (r_e.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", nt_errstr(r_e.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
-
- name_idx = 0;
-
- for (i = 0; i < *num_dom_groups; i++) {
+ *num_sam_users = r_e.num_entries2;
+ if (*num_sam_users > MAX_SAM_ENTRIES) {
+ *num_sam_users = MAX_SAM_ENTRIES;
+ DEBUG(2,("do_samr_enum_dom_users: sam user entries limited to %d\n",
+ *num_sam_users));
+ }
- (*dom_groups)[i].rid = r.sam[i].rid;
+ *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users));
+
+ if ((*sam) == NULL)
+ *num_sam_users = 0;
- if (r.sam[i].hdr_name.buffer) {
- unistr2_to_ascii((*dom_groups)[i].acct_name,
- &r.uni_grp_name[name_idx],
- sizeof(fstring) - 1);
+ for (i = 0; i < *num_sam_users; i++) {
+ (*sam)[i].smb_userid = r_e.sam[i].rid;
+ if (r_e.sam[i].hdr_name.buffer) {
+ char *acct_name = dos_unistrn2(r_e.uni_acct_name[name_idx].buffer,
+ r_e.uni_acct_name[name_idx].uni_str_len);
+ fstrcpy((*sam)[i].acct_name, acct_name);
name_idx++;
+ } else {
+ memset((char *)(*sam)[i].acct_name, '\0', sizeof((*sam)[i].acct_name));
}
- *start_idx = r.next_idx;
+ DEBUG(5,("do_samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
+ i, (*sam)[i].smb_userid, (*sam)[i].acct_name));
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata );
- return result;
+ return True;
}
+#endif
-/* Query alias members */
-
-NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol, uint32 *num_mem,
- DOM_SID **sids)
+/****************************************************************************
+do a SAMR Connect
+****************************************************************************/
+BOOL do_samr_connect(struct cli_state *cli,
+ char *srv_name, uint32 unknown_0,
+ POLICY_HND *connect_pol)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_ALIASMEM q;
- SAMR_R_QUERY_ALIASMEM r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 i;
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_CONNECT q_o;
+ SAMR_R_CONNECT r_o;
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ if (srv_name == NULL || connect_pol == NULL)
+ return False;
- /* Initialise parse structures */
+ /* create and send a MSRPC command with api SAMR_CONNECT */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- /* Marshall data and send request */
+ DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
+ srv_name, unknown_0));
- init_samr_q_query_aliasmem(&q, alias_pol);
+ /* store the parameters */
+ init_samr_q_connect(&q_o, srv_name, unknown_0);
- if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
- goto done;
+ /* turn parameters into data stream */
+ if(!samr_io_q_connect("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Unmarshall response */
-
- if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
- goto done;
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_CONNECT, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
+ prs_mem_free(&data);
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
+ if(!samr_io_r_connect("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
-
- *num_mem = r.num_sids;
-
- if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_CONNECT: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- for (i = 0; i < *num_mem; i++) {
- (*sids)[i] = r.sid[i].sid;
- }
+ memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
-/* Open handle on an alias */
-
-NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 alias_rid, POLICY_HND *alias_pol)
+/****************************************************************************
+do a SAMR Open User
+****************************************************************************/
+BOOL do_samr_open_user(struct cli_state *cli,
+ POLICY_HND *pol, uint32 unk_0, uint32 rid,
+ POLICY_HND *user_pol)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_OPEN_ALIAS q;
- SAMR_R_OPEN_ALIAS r;
- NTSTATUS result;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_OPEN_USER q_o;
+ SAMR_R_OPEN_USER r_o;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ if (pol == NULL || user_pol == NULL)
+ return False;
- /* Marshall data and send request */
+ /* create and send a MSRPC command with api SAMR_OPEN_USER */
- init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ DEBUG(4,("SAMR Open User. unk_0: %08x RID:%x\n",
+ unk_0, rid));
- /* Unmarshall response */
+ /* store the parameters */
+ init_samr_q_open_user(&q_o, pol, unk_0, rid);
- if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ /* turn parameters into data stream */
+ if(!samr_io_q_open_user("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
-
- if (NT_STATUS_IS_OK(result = r.status)) {
- *alias_pol = r.pol;
-#ifdef __INSURE__
- alias_pol->marker = malloc(1);
-#endif
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_OPEN_USER, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Query domain info */
-
-NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint16 switch_value,
- SAM_UNK_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_DOMAIN_INFO q;
- SAMR_R_QUERY_DOMAIN_INFO 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);
+ prs_mem_free(&data);
- /* Marshall data and send request */
-
- init_samr_q_query_dom_info(&q, domain_pol, switch_value);
-
- if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
- goto done;
+ if(!samr_io_r_open_user("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
-
- /* Unmarshall response */
-
- r.ctr = ctr;
-
- if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
- goto done;
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_OPEN_USER: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
+ memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
-/* Query display info */
-
-NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 *start_idx,
- uint16 switch_value, uint32 *num_entries,
- uint32 max_entries, SAM_DISPINFO_CTR *ctr)
+/****************************************************************************
+do a SAMR Open Domain
+****************************************************************************/
+BOOL do_samr_open_domain(struct cli_state *cli,
+ POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
+ POLICY_HND *domain_pol)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_DISPINFO q;
- SAMR_R_QUERY_DISPINFO r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ prs_struct data;
+ prs_struct rdata;
+ pstring sid_str;
+ SAMR_Q_OPEN_DOMAIN q_o;
+ SAMR_R_OPEN_DOMAIN r_o;
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ if (connect_pol == NULL || sid == NULL || domain_pol == NULL)
+ return False;
- /* Initialise parse structures */
+ /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- /* Marshall data and send request */
+ sid_to_string(sid_str, sid);
+ DEBUG(4,("SAMR Open Domain. SID:%s RID:%x\n", sid_str, rid));
- init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
- *start_idx, max_entries);
+ /* store the parameters */
+ init_samr_q_open_domain(&q_o, connect_pol, rid, sid);
- if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
- goto done;
+ /* turn parameters into data stream */
+ if(!samr_io_q_open_domain("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Unmarshall response */
-
- r.ctr = ctr;
-
- if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
- goto done;
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
+ prs_mem_free(&data);
- result = r.status;
+ if(!samr_io_r_open_domain("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
+ }
- if (!NT_STATUS_IS_OK(result) &&
- NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
- goto done;
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- *num_entries = r.num_entries;
- *start_idx += r.num_entries; /* No next_idx in this structure! */
+ memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
-/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
- looked up in one packet. */
+#if 0
-NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 flags,
- uint32 num_rids, uint32 *rids,
- uint32 *num_names, char ***names,
- uint32 **name_types)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_LOOKUP_RIDS q;
- SAMR_R_LOOKUP_RIDS r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 i;
+/* CURRENTLY DOES NOT COMPILE AND IS NOT USED ANYWHERE. JRA. */
- 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"));
- }
+/****************************************************************************
+do a SAMR Query Unknown 12
+****************************************************************************/
+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])
+{
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_LOOKUP_RIDS q_o;
+ SAMR_R_LOOKUP_RIDS r_o;
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
+ num_aliases == NULL || als_names == NULL || num_als_users == NULL )
+ return False;
- /* Initialise parse structures */
+ /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- /* Marshall data and send request */
+ DEBUG(4,("SAMR Query Unknown 12.\n"));
- init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
- num_rids, rids);
+ /* store the parameters */
+ init_samr_q_lookup_rids(&q_o, pol, rid, num_gids, gids);
- if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
- goto done;
+ /* turn parameters into data stream */
+ if(!samr_io_q_lookup_rids("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Unmarshall response */
-
- if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
- goto done;
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
+ prs_mem_free(&data);
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
+ if(!samr_io_r_lookup_rids("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
-
- if (r.num_names1 == 0) {
- *num_names = 0;
- *names = NULL;
- goto done;
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- *num_names = r.num_names1;
- *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
- *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
+ if (r_o.ptr_aliases != 0 && r_o.ptr_als_usrs != 0 &&
+ r_o.num_als_usrs1 == r_o.num_aliases1) {
+ int i;
- for (i = 0; i < r.num_names1; i++) {
- fstring tmp;
+ *num_aliases = r_o.num_aliases1;
- unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
- (*names)[i] = talloc_strdup(mem_ctx, tmp);
- (*name_types)[i] = r.type[i];
+ for (i = 0; i < r_o.num_aliases1; i++) {
+ fstrcpy(als_names[i], dos_unistrn2(r_o.uni_als_name[i].buffer,
+ r_o.uni_als_name[i].uni_str_len));
+ }
+ for (i = 0; i < r_o.num_als_usrs1; i++) {
+ num_als_users[i] = r_o.num_als_usrs[i];
+ }
+ } else if (r_o.ptr_aliases == 0 && r_o.ptr_als_usrs == 0) {
+ *num_aliases = 0;
+ } else {
+ prs_mem_free(&rdata);
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
+#endif
-/* Lookup names */
-
-NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 flags,
- uint32 num_names, const char **names,
- uint32 *num_rids, uint32 **rids,
- uint32 **rid_types)
+/****************************************************************************
+do a SAMR Query User Groups
+****************************************************************************/
+BOOL do_samr_query_usergroups(struct cli_state *cli,
+ POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_LOOKUP_NAMES q;
- SAMR_R_LOOKUP_NAMES r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 i;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise parse structures */
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_QUERY_USERGROUPS q_o;
+ SAMR_R_QUERY_USERGROUPS r_o;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ if (pol == NULL || gid == NULL || num_groups == 0)
+ return False;
- /* Marshall data and send request */
+ /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
- init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
- num_names, names);
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
- goto done;
- }
+ DEBUG(4,("SAMR Query User Groups.\n"));
- /* Unmarshall response */
-
- if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
- goto done;
- }
+ /* store the parameters */
+ init_samr_q_query_usergroups(&q_o, pol);
- /* Return output parameters */
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
- }
-
- if (r.num_rids1 == 0) {
- *num_rids = 0;
- goto done;
+ /* turn parameters into data stream */
+ if(!samr_io_q_query_usergroups("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- *num_rids = r.num_rids1;
- *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
- *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
-
- for (i = 0; i < r.num_rids1; i++) {
- (*rids)[i] = r.rids[i];
- (*rid_types)[i] = r.types[i];
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* 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,
- uint32 acb_info, uint32 unknown,
- POLICY_HND *user_pol, uint32 *rid)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_CREATE_USER q;
- SAMR_R_CREATE_USER r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ prs_mem_free(&data);
- /* Initialise parse structures */
+ /* get user info */
+ r_o.gid = gid;
- 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_user(&q, domain_pol, acct_name, acb_info, unknown);
-
- if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
- goto done;
+ if(!samr_io_r_query_usergroups("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
-
- /* Return output parameters */
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- if (user_pol)
- *user_pol = r.user_pol;
+ *num_groups = r_o.num_entries;
- if (rid)
- *rid = r.user_rid;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
-/* Set userinfo */
-
-NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- 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;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+#if 0
- /* Initialise parse structures */
+/* CURRENTLY DOES NOT COMPILE WITH THE NEW SAMR PARSE CODE. JRA */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+/****************************************************************************
+do a SAMR Query User Info
+****************************************************************************/
+BOOL do_samr_query_userinfo(struct cli_state *cli,
+ POLICY_HND *pol, uint16 switch_value, void* usr)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_QUERY_USERINFO q_o;
+ SAMR_R_QUERY_USERINFO r_o;
- /* Marshall data and send request */
+ if (pol == NULL || usr == NULL || switch_value == 0)
+ return False;
- q.ctr = ctr;
+ /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
- init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
- ctr->info.id);
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
- goto done;
- }
+ DEBUG(4,("SAMR Query User Info. level: %d\n", switch_value));
- /* Unmarshall response */
+ /* store the parameters */
+ init_samr_q_query_userinfo(&q_o, pol, switch_value);
- if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
- goto done;
+ /* turn parameters into data stream */
+ if(!samr_io_q_query_userinfo("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
-
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&data);
- return result;
-}
+ /* get user info */
+ r_o.info.id = usr;
-/* Set userinfo2 */
-
-NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- 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;
-
- 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_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
-
- if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
- goto done;
+ if(!samr_io_r_query_userinfo("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
-
- /* Unmarshall response */
-
- if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
- goto done;
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
+ if (r_o.switch_value != switch_value) {
+ DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
+ r_o.switch_value));
+ prs_mem_free(&rdata);
+ return False;
+ }
- if (!NT_STATUS_IS_OK(result = r.status)) {
- goto done;
+ if (r_o.ptr == 0) {
+ prs_mem_free(&rdata);
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
-/* Delete domain user */
+#endif
-NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol)
+/****************************************************************************
+do a SAMR Close
+****************************************************************************/
+BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd)
{
- prs_struct qbuf, rbuf;
- SAMR_Q_DELETE_DOM_USER q;
- SAMR_R_DELETE_DOM_USER r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ prs_struct data;
+ prs_struct rdata;
+ SAMR_Q_CLOSE_HND q_c;
+ SAMR_R_CLOSE_HND r_c;
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ if (hnd == NULL)
+ return False;
- /* Initialise parse structures */
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 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 SAMR_CLOSE_HND */
- /* Marshall data and send request */
+ DEBUG(4,("SAMR Close\n"));
- init_samr_q_delete_dom_user(&q, user_pol);
+ /* store the parameters */
+ init_samr_q_close_hnd(&q_c, hnd);
- if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
- goto done;
+ /* turn parameters into data stream */
+ if(!samr_io_q_close_hnd("", &q_c, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Unmarshall response */
-
- if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
- goto done;
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/* Query user security object */
-
-NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_QUERY_SEC_OBJ q;
- SAMR_R_QUERY_SEC_OBJ 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);
-
- /* Marshall data and send request */
-
- init_samr_q_query_sec_obj(&q, user_pol, switch_value);
+ prs_mem_free(&data);
- if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
- goto done;
+ if(!samr_io_r_close_hnd("", &r_c, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
- /* Unmarshall response */
-
- if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
- goto done;
+ if (r_c.status != 0) {
+ /* report error code */
+ DEBUG(0,("SAMR_CLOSE_HND: %s\n", nt_errstr(r_c.status)));
+ prs_mem_free(&rdata);
+ return False;
}
- /* Return output parameters */
-
- result = r.status;
- *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- 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, uint16 *unk_2)
-{
- prs_struct qbuf, rbuf;
- SAMR_Q_GET_DOM_PWINFO q;
- SAMR_R_GET_DOM_PWINFO r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ /* check that the returned policy handle is all zeros */
- /* Initialise parse structures */
+ if (IVAL(&r_c.pol.data1,0) || IVAL(&r_c.pol.data2,0) || SVAL(&r_c.pol.data3,0) ||
+ SVAL(&r_c.pol.data4,0) || IVAL(r_c.pol.data5,0) || IVAL(r_c.pol.data5,4) ) {
+ DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
+ prs_mem_free(&rdata);
+ return False;
+ }
- 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;
- if (unk_2)
- *unk_2 = r.unk_2;
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rdata);
- return result;
+ return True;
}
diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c
index 18e17758d6..5292569ed4 100644
--- a/source3/rpc_client/cli_spoolss.c
+++ b/source3/rpc_client/cli_spoolss.c
@@ -1,2156 +1,820 @@
/*
- 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) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Paul Ashton 1997-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"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
+
+/****************************************************************************
+do a SPOOLSS Enum Printer Drivers
+****************************************************************************/
+uint32 spoolss_enum_printerdrivers(const char *srv_name, const char *environment,
+ uint32 level, NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed, uint32 *returned)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ENUMPRINTERDRIVERS q_o;
+ SPOOL_R_ENUMPRINTERDRIVERS r_o;
+ TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
+ prs_init(&rbuf, 0, ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
+
+ DEBUG(5,("SPOOLSS Enum Printer Drivers (Server: %s Environment: %s level: %d)\n",
+ srv_name, environment, level));
+
+ make_spoolss_q_enumprinterdrivers(&q_o, srv_name, environment,
+ level, buffer, offered);
+
+ /* turn parameters into data stream */
+ if (spoolss_io_q_enumprinterdrivers("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_ENUMPRINTERDRIVERS, &buf, &rbuf))
+ {
+ prs_mem_free(&buf);
+ ZERO_STRUCT(r_o);
+
+ prs_switch_type(&buffer->prs, UNMARSHALL);
+ prs_set_offset(&buffer->prs, 0);
+ r_o.buffer=buffer;
+
+ if(spoolss_io_r_enumprinterdrivers("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ DEBUG(3,("SPOOLSS_ENUMPRINTERDRIVERS: %s\n", nt_errstr(r_o.status)));
+ }
+ *needed=r_o.needed;
+ *returned=r_o.returned;
+ }
+ }
-/** @defgroup spoolss SPOOLSS - NT printing routines
- * @ingroup rpc_client
- *
- * @{
- **/
-
-/**********************************************************************
- Initialize a new spoolss buff for use by a client rpc
-**********************************************************************/
-static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
-{
- buffer->ptr = (size != 0);
- buffer->size = size;
- buffer->string_at_end = size;
- prs_init(&buffer->prs, size, ctx, MARSHALL);
- buffer->struct_start = prs_offset(&buffer->prs);
-}
-
-/*********************************************************************
- Decode various spoolss rpc's and info levels
- ********************************************************************/
-
-/**********************************************************************
-**********************************************************************/
-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));
-
- buffer->prs.data_offset=0;
-
- for (i=0; i<returned; i++) {
- smb_io_printer_info_0("", buffer, &inf[i], 0);
- }
-
- *info=inf;
-}
-
-/**********************************************************************
-**********************************************************************/
-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));
-
- buffer->prs.data_offset=0;
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- for (i=0; i<returned; i++) {
- smb_io_printer_info_1("", buffer, &inf[i], 0);
- }
+ cli_connection_unlink(con);
- *info=inf;
+ return r_o.status;
}
-/**********************************************************************
-**********************************************************************/
-static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 returned, PRINTER_INFO_2 **info)
+/****************************************************************************
+do a SPOOLSS Enum Printers
+****************************************************************************/
+uint32 spoolss_enum_printers(uint32 flags, fstring srv_name, uint32 level,
+ NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed, uint32 *returned)
{
- uint32 i;
- PRINTER_INFO_2 *inf;
-
- inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ENUMPRINTERS q_o;
+ SPOOL_R_ENUMPRINTERS r_o;
+ TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
- buffer->prs.data_offset=0;
+ struct cli_connection *con = NULL;
- for (i=0; i<returned; i++) {
- /* a little initialization as we go */
- inf[i].secdesc = NULL;
- smb_io_printer_info_2("", buffer, &inf[i], 0);
- }
-
- *info=inf;
-}
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ return False;
-/**********************************************************************
-**********************************************************************/
-static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 returned, PRINTER_INFO_3 **info)
-{
- uint32 i;
- PRINTER_INFO_3 *inf;
+ prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
+ prs_init(&rbuf, 0, ctx, UNMARSHALL);
- inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
+ /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
- buffer->prs.data_offset=0;
+ DEBUG(5,("SPOOLSS Enum Printers (Server: %s level: %d)\n", srv_name, level));
- for (i=0; i<returned; i++) {
- inf[i].secdesc = NULL;
- smb_io_printer_info_3("", buffer, &inf[i], 0);
- }
+ make_spoolss_q_enumprinters(&q_o, flags, "", level, buffer, offered);
- *info=inf;
-}
+ /* turn parameters into data stream */
+ if (spoolss_io_q_enumprinters("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_ENUMPRINTERS, &buf, &rbuf))
+ {
+ ZERO_STRUCT(r_o);
-/**********************************************************************
-**********************************************************************/
-static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 returned, PORT_INFO_1 **info)
-{
- uint32 i;
- PORT_INFO_1 *inf;
+ prs_switch_type(&buffer->prs, UNMARSHALL);
+ prs_set_offset(&buffer->prs, 0);
+ r_o.buffer=buffer;
- inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
+ if(new_spoolss_io_r_enumprinters("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ /* report error code */
+ DEBUG(3,("SPOOLSS_ENUMPRINTERS: %s\n", nt_errstr(r_o.status)));
+ }
- prs_set_offset(&buffer->prs, 0);
+ *needed=r_o.needed;
+ *returned=r_o.returned;
+ }
- for (i=0; i<returned; i++) {
- smb_io_port_info_1("", buffer, &(inf[i]), 0);
}
- *info=inf;
-}
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
-/**********************************************************************
-**********************************************************************/
-static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 returned, PORT_INFO_2 **info)
-{
- uint32 i;
- PORT_INFO_2 *inf;
-
- inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
-
- prs_set_offset(&buffer->prs, 0);
-
- for (i=0; i<returned; i++) {
- smb_io_port_info_2("", buffer, &(inf[i]), 0);
- }
+ cli_connection_unlink(con);
- *info=inf;
+ return r_o.status;
}
-/**********************************************************************
-**********************************************************************/
-static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 returned, DRIVER_INFO_1 **info)
+/****************************************************************************
+do a SPOOLSS Enum Ports
+****************************************************************************/
+uint32 spoolss_enum_ports(fstring srv_name, uint32 level,
+ NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed, uint32 *returned)
{
- uint32 i;
- DRIVER_INFO_1 *inf;
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ENUMPORTS q_o;
+ SPOOL_R_ENUMPORTS r_o;
+ TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
- inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
+ struct cli_connection *con = NULL;
- buffer->prs.data_offset=0;
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ return False;
- for (i=0; i<returned; i++) {
- smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
- }
+ prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
+ prs_init(&rbuf, 0, ctx, UNMARSHALL);
- *info=inf;
-}
+ /* create and send a MSRPC command with api SPOOLSS_ENUMPORTS */
-/**********************************************************************
-**********************************************************************/
-static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 returned, DRIVER_INFO_2 **info)
-{
- uint32 i;
- DRIVER_INFO_2 *inf;
+ DEBUG(5,("SPOOLSS Enum Ports (Server: %s level: %d)\n", srv_name, level));
- inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
+ make_spoolss_q_enumports(&q_o, "", level, buffer, offered);
- buffer->prs.data_offset=0;
+ /* turn parameters into data stream */
+ if (spoolss_io_q_enumports("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_ENUMPORTS, &buf, &rbuf))
+ {
+ prs_mem_free(&buf );
+ ZERO_STRUCT(r_o);
- for (i=0; i<returned; i++) {
- smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
- }
+ prs_switch_type(&buffer->prs, UNMARSHALL);
+ prs_set_offset(&buffer->prs, 0);
+ r_o.buffer=buffer;
- *info=inf;
-}
-
-/**********************************************************************
-**********************************************************************/
-static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 returned, DRIVER_INFO_3 **info)
-{
- uint32 i;
- DRIVER_INFO_3 *inf;
-
- inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
-
- buffer->prs.data_offset=0;
-
- for (i=0; i<returned; i++) {
- smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
+ if(new_spoolss_io_r_enumports("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ DEBUG(3,("SPOOLSS_ENUMPORTS: %s\n", nt_errstr(r_o.status)));
+ }
+
+ *needed=r_o.needed;
+ *returned=r_o.returned;
+ }
}
- *info=inf;
-}
-
-/**********************************************************************
-**********************************************************************/
-static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 returned, DRIVER_DIRECTORY_1 **info
-)
-{
- DRIVER_DIRECTORY_1 *inf;
-
- inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
-
- prs_set_offset(&buffer->prs, 0);
-
- smb_io_driverdir_1("", buffer, inf, 0);
-
- *info=inf;
-}
-
-/** Return a handle to the specified printer or print server.
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- *
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param printername The name of the printer or print server to be
- * opened in UNC format.
- *
- * @param datatype Specifies the default data type for the printer.
- *
- * @param access_required The access rights requested on the printer or
- * print server.
- *
- * @param station The UNC name of the requesting workstation.
- *
- * @param username The name of the user requesting the open.
- *
- * @param pol Returned policy handle.
- */
-
-/*********************************************************************************
- Win32 API - OpenPrinter()
- ********************************************************************************/
-
-WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- char *printername, char *datatype, uint32 access_required,
- char *station, char *username, POLICY_HND *pol)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_OPEN_PRINTER_EX q;
- SPOOL_R_OPEN_PRINTER_EX 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_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) ||
- !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- result = r.status;
+ cli_connection_unlink(con);
- if (W_ERROR_IS_OK(result))
- *pol = r.handle;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/** Close a printer handle
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- *
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param pol Policy handle of printer or print server to close.
- */
-/*********************************************************************************
- Win32 API - ClosePrinter()
- ********************************************************************************/
-
-WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_CLOSEPRINTER q;
- SPOOL_R_CLOSEPRINTER 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_closeprinter(&q, pol);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (W_ERROR_IS_OK(result))
- *pol = r.handle;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ return r_o.status;
}
-/** Enumerate printers on a print server.
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param offered Buffer size offered in the request.
- * @param needed Number of bytes needed to complete the request.
- * may be NULL.
- *
- * @param flags Selected from PRINTER_ENUM_* flags.
- * @param level Request information level.
- *
- * @param num_printers Pointer to number of printers returned. May be
- * NULL.
- * @param ctr Return structure for printer information. May
- * be NULL.
- */
-/*********************************************************************************
- Win32 API - EnumPrinters()
- ********************************************************************************/
-
-WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- uint32 flags, uint32 level,
- uint32 *num_printers, PRINTER_INFO_CTR *ctr)
+/****************************************************************************
+do a SPOOLSS Enum Jobs
+****************************************************************************/
+uint32 spoolss_enum_jobs(const POLICY_HND *hnd, uint32 firstjob, uint32 numofjobs,
+ uint32 level, NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed, uint32 *returned)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMPRINTERS q;
- SPOOL_R_ENUMPRINTERS r;
- NEW_BUFFER buffer;
- WERROR result = W_ERROR(ERRgeneral);
- fstring server;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper (server);
-
- /* Initialise input parameters */
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ENUMJOBS q_o;
+ SPOOL_R_ENUMJOBS r_o;
+ TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
- init_buffer(&buffer, offered, mem_ctx);
+ if (hnd == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
+ prs_init(&rbuf, 0, ctx, UNMARSHALL);
- make_spoolss_q_enumprinters(&q, flags, server, level, &buffer,
- offered);
+ /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf))
- goto done;
+ DEBUG(5,("SPOOLSS Enum Jobs level: %d)\n", level));
- /* Unmarshall response */
+ make_spoolss_q_enumjobs(&q_o, hnd, firstjob, numofjobs, level, buffer, offered);
- 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;
-
- 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);
+ /* turn parameters into data stream */
+ if (spoolss_io_q_enumjobs("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, SPOOLSS_ENUMJOBS, &buf, &rbuf))
+ {
+ ZERO_STRUCT(r_o);
+ prs_mem_free(&buf );
- return result;
-}
+ r_o.buffer=buffer;
-/*********************************************************************************
- Win32 API - EnumPorts()
- ********************************************************************************/
-/** Enumerate printer ports on a print server.
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param offered Buffer size offered in the request.
- * @param needed Number of bytes needed to complete the request.
- * May be NULL.
- *
- * @param level Requested information level.
- *
- * @param num_ports Pointer to number of ports returned. May be NULL.
- * @param ctr Pointer to structure holding port information.
- * May be NULL.
- */
-
-WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- uint32 level, int *num_ports, PORT_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMPORTS q;
- SPOOL_R_ENUMPORTS r;
- NEW_BUFFER buffer;
- WERROR result = W_ERROR(ERRgeneral);
- fstring server;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- slprintf (server, sizeof(fstring)-1, "\\\\%s", 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);
-
- make_spoolss_q_enumports(&q, server, level, &buffer, offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
- if (needed)
- *needed = r.needed;
+ if(spoolss_io_r_enumjobs("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ DEBUG(3,("SPOOLSS_ENUMJOBS: %s\n", nt_errstr(r_o.status)));
+ }
+ *needed=r_o.needed;
+ *returned=r_o.returned;
+ }
}
-
- result = r.status;
- /* Return output parameters */
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- if (num_ports)
- *num_ports = r.returned;
-
- 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);
-
- return result;
+ return r_o.status;
}
-/*********************************************************************************
- Win32 API - GetPrinter()
- ********************************************************************************/
-
-WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *pol, uint32 level,
- PRINTER_INFO_CTR *ctr)
+/***************************************************************************
+do a SPOOLSS Enum printer datas
+****************************************************************************/
+uint32 spoolss_enum_printerdata(const POLICY_HND *hnd, uint32 idx,
+ uint32 *valuelen, uint16 *value, uint32 *rvaluelen,
+ uint32 *type, uint32 *datalen, uint8 *data,
+ uint32 *rdatalen)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTER q;
- SPOOL_R_GETPRINTER r;
- NEW_BUFFER buffer;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise input parameters */
-
- init_buffer(&buffer, offered, mem_ctx);
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ENUMPRINTERDATA q_o;
+ SPOOL_R_ENUMPRINTERDATA r_o;
+ TALLOC_CTX *mem_ctx = NULL;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ if (hnd == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
- 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;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_getprinter("", &r, &rbuf, 0))
- goto done;
-
- if (needed)
- *needed = r.needed;
-
- /* Return output parameters */
-
- result = r.status;
-
- 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;
- }
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
+ return False;
}
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api SPOOLSS_ENUMPRINTERDATA*/
+
+ DEBUG(4,("SPOOLSS Enum Printer data\n"));
+
+ make_spoolss_q_enumprinterdata(&q_o, hnd, idx, *valuelen, *datalen);
+
+ /* turn parameters into data stream */
+ if (spoolss_io_q_enumprinterdata("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, SPOOLSS_ENUMPRINTERDATA, &buf, &rbuf))
+ {
+ ZERO_STRUCT(r_o);
+ prs_mem_free(&buf );
+
+ r_o.data=data;
+ r_o.value=value;
+
+ if(spoolss_io_r_enumprinterdata("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ DEBUG(3,("SPOOLSS_ENUMPRINTERDATA: %s\n", nt_errstr(r_o.status)));
+ }
+
+ *valuelen=r_o.valuesize;
+ *rvaluelen=r_o.realvaluesize;
+ *type=r_o.type;
+ *datalen=r_o.datasize;
+ *rdatalen=r_o.realdatasize;
- return result;
-}
-
-/*********************************************************************************
- Win32 API - SetPrinter()
- ********************************************************************************/
-/** Set printer info
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param pol Policy handle on printer to set info.
- * @param level Information level to set.
- * @param ctr Pointer to structure holding printer information.
- * @param command Specifies the action performed. See
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp
- * 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)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_SETPRINTER q;
- SPOOL_R_SETPRINTER 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_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))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/*********************************************************************************
- Win32 API - GetPrinterDriver()
- ********************************************************************************/
-/** Get installed printer drivers for a given printer
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- *
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param offered Buffer size offered in the request.
- * @param needed Number of bytes needed to complete the request.
- * may be NULL.
- *
- * @param pol Pointer to an open policy handle for the printer
- * opened with cli_spoolss_open_printer_ex().
- * @param level Requested information level.
- * @param env The print environment or archictecture. This is
- * "Windows NT x86" for NT4.
- * @param ctr Returned printer driver information.
- */
-
-WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *pol, uint32 level,
- char *env, PRINTER_DRIVER_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTERDRIVER2 q;
- SPOOL_R_GETPRINTERDRIVER2 r;
- NEW_BUFFER buffer;
- WERROR result = W_ERROR(ERRgeneral);
- fstring server;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- 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);
-
- 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;
-
- /* Unmarshall response */
-
- if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) {
- if (needed)
- *needed = r.needed;
+ }
}
- result = r.status;
-
- /* Return output parameters */
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- if (!ctr)
- 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;
- }
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ return r_o.status;
}
-/*********************************************************************************
- Win32 API - EnumPrinterDrivers()
- ********************************************************************************/
-/**********************************************************************
- * Get installed printer drivers for a given printer
- */
-WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- uint32 level, char *env,
- uint32 *num_drivers,
- PRINTER_DRIVER_CTR *ctr)
+/****************************************************************************
+do a SPOOLSS Enum printer datas
+****************************************************************************/
+uint32 spoolss_getprinter(const POLICY_HND *hnd, uint32 level,
+ NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMPRINTERDRIVERS q;
- SPOOL_R_ENUMPRINTERDRIVERS r;
- NEW_BUFFER buffer;
- WERROR result = W_ERROR(ERRgeneral);
- fstring server;
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_GETPRINTER q_o;
+ SPOOL_R_GETPRINTER r_o;
+ TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ if (hnd == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
- slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper (server);
+ prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
+ prs_init(&rbuf, 0, ctx, UNMARSHALL);
- /* Initialise input parameters */
+ /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
- init_buffer(&buffer, offered, mem_ctx);
+ DEBUG(5,("SPOOLSS Enum Printer data)\n"));
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ make_spoolss_q_getprinter(&q_o, hnd, level, buffer, offered);
- /* Write the request */
+ /* turn parameters into data stream */
+ if (spoolss_io_q_getprinter("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, SPOOLSS_GETPRINTER, &buf, &rbuf))
+ {
+ ZERO_STRUCT(r_o);
+ prs_mem_free(&buf );
- make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer,
- offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0))
- goto done;
-
- if (needed)
- *needed = r.needed;
-
- if (num_drivers)
- *num_drivers = r.returned;
+ prs_switch_type(&buffer->prs, UNMARSHALL);
+ prs_set_offset(&buffer->prs, 0);
+ r_o.buffer=buffer;
- result = r.status;
-
- /* 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;
+ if(!spoolss_io_r_getprinter("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ DEBUG(3,("SPOOLSS_GETPRINTER: %s\n", nt_errstr(r_o.status)));
+ }
+ *needed=r_o.needed;
}
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-
-/*********************************************************************************
- Win32 API - GetPrinterDriverDirectory()
- ********************************************************************************/
-/**********************************************************************
- * Get installed printer drivers for a given printer
- */
-WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- uint32 level, char *env,
- DRIVER_DIRECTORY_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTERDRIVERDIR q;
- SPOOL_R_GETPRINTERDRIVERDIR r;
- NEW_BUFFER buffer;
- WERROR result = W_ERROR(ERRgeneral);
- fstring server;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper (server);
-
- /* Initialise input parameters */
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- init_buffer(&buffer, offered, mem_ctx);
-
- 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 */
-
- if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
- &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) {
- if (needed)
- *needed = r.needed;
- }
-
- /* Return output parameters */
-
- result = r.status;
-
- if (W_ERROR_IS_OK(result)) {
- switch (level) {
- case 1:
- decode_printerdriverdir_1(mem_ctx, r.buffer, 1,
- &ctr->info1);
- break;
- }
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/*********************************************************************************
- Win32 API - AddPrinterDriver()
- ********************************************************************************/
-/**********************************************************************
- * Install a printer driver
- */
-WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
- TALLOC_CTX *mem_ctx, uint32 level,
- PRINTER_DRIVER_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ADDPRINTERDRIVER q;
- SPOOL_R_ADDPRINTERDRIVER r;
- WERROR result = W_ERROR(ERRgeneral);
- fstring server;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- 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);
-
- /* Write the request */
-
- make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/*********************************************************************************
- Win32 API - AddPrinter()
- ********************************************************************************/
-/**********************************************************************
- * Install a printer
- */
-WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 level, PRINTER_INFO_CTR*ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ADDPRINTEREX q;
- SPOOL_R_ADDPRINTEREX r;
- WERROR result = W_ERROR(ERRgeneral);
- fstring server,
- client,
- user;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- 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);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Write the request */
-
- make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user,
- level, ctr);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ return r_o.status;
}
-/*********************************************************************************
- Win32 API - DeltePrinterDriver()
- ********************************************************************************/
-/**********************************************************************
- * Delete a Printer Driver from the server (does not remove
- * the driver files
- */
-WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
- TALLOC_CTX *mem_ctx, char *arch,
- char *driver)
+/****************************************************************************
+do a SPOOLSS Enum printer driver
+****************************************************************************/
+uint32 spoolss_getprinterdriver(const POLICY_HND *hnd,
+ const char *environment, uint32 level,
+ NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_DELETEPRINTERDRIVER q;
- SPOOL_R_DELETEPRINTERDRIVER r;
- WERROR result = W_ERROR(ERRgeneral);
- fstring server;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_GETPRINTERDRIVER2 q_o;
+ SPOOL_R_GETPRINTERDRIVER2 r_o;
+ TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
+ if (hnd == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
- /* Initialise input parameters */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
+ prs_init(&rbuf, 0, ctx, UNMARSHALL);
- slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper (server);
+ /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
- /* Write the request */
+ DEBUG(5,("SPOOLSS Enum Printer driver)\n"));
- make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver);
+ make_spoolss_q_getprinterdriver2(&q_o, hnd, environment, level, 2, 0, buffer, offered);
- /* Marshall data and send request */
+ /* turn parameters into data stream */
+ if (spoolss_io_q_getprinterdriver2("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, SPOOLSS_GETPRINTERDRIVER2, &buf, &rbuf))
+ {
+ ZERO_STRUCT(r_o);
+ prs_mem_free(&buf );
- if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
- goto done;
+ prs_switch_type(&buffer->prs, UNMARSHALL);
+ prs_set_offset(&buffer->prs, 0);
+ r_o.buffer=buffer;
- /* Unmarshall response */
+ if(spoolss_io_r_getprinterdriver2("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ DEBUG(3,("SPOOLSS_GETPRINTERDRIVER2: %s\n", nt_errstr(r_o.status)));
+ }
- if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
+ *needed=r_o.needed;
+ }
+ }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- return result;
+ return r_o.status;
}
-/*********************************************************************************
- Win32 API - GetPrinterProcessorDirectory()
- ********************************************************************************/
-
-WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- char *name, char *environment,
- fstring procdir)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTPROCESSORDIRECTORY q;
- SPOOL_R_GETPRINTPROCESSORDIRECTORY r;
- int level = 1;
- WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
-
- 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_buffer(&buffer, offered, mem_ctx);
- make_spoolss_q_getprintprocessordirectory(
- &q, name, environment, level, &buffer, offered);
- /* Marshall data and send request */
-
- if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
- &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (W_ERROR_IS_OK(result))
- fstrcpy(procdir, "Not implemented!");
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/** Add a form to a printer.
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param handle Policy handle opened with cli_spoolss_open_printer_ex
- * or cli_spoolss_addprinterex.
- * @param level Form info level to add - should always be 1.
- * @param form A pointer to the form to be added.
- *
- */
-
-WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *handle, uint32 level, FORM *form)
+/****************************************************************************
+do a SPOOLSS Open Printer Ex
+****************************************************************************/
+BOOL spoolss_open_printer_ex( const char *printername,
+ const char *datatype, uint32 access_required,
+ const char *station, const char *username,
+ POLICY_HND *hnd)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ADDFORM q;
- SPOOL_R_ADDFORM 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_addform(&q, handle, level, form);
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_OPEN_PRINTER_EX q_o;
+ BOOL valid_pol = False;
+ fstring srv_name;
+ char *s = NULL;
+ struct cli_connection *con = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
- /* Marshall data and send request */
-
- if (!spoolss_io_q_addform("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_addform("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/** Set a form on a printer.
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param handle Policy handle opened with cli_spoolss_open_printer_ex
- * or cli_spoolss_addprinterex.
- * @param level Form info level to set - should always be 1.
- * @param form A pointer to the form to be set.
- *
- */
-
-WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *handle, uint32 level, char *form_name,
- FORM *form)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_SETFORM q;
- SPOOL_R_SETFORM r;
- WERROR result = W_ERROR(ERRgeneral);
+ memset(srv_name, 0, sizeof(srv_name));
+ fstrcpy(srv_name, printername);
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ s = strchr_m(&srv_name[2], '\\');
+ if (s != NULL)
+ *s = '\0';
- /* Initialise parse structures */
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ return False;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ if (hnd == NULL)
+ return False;
- /* Initialise input parameters */
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
+ return False;
+ }
+ prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- make_spoolss_q_setform(&q, handle, level, form_name, form);
-
- /* Marshall data and send request */
+ /* create and send a MSRPC command with api SPOOLSS_OPENPRINTEREX */
- if (!spoolss_io_q_setform("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf))
- goto done;
+ DEBUG(5,("SPOOLSS Open Printer Ex\n"));
- /* Unmarshall response */
+ make_spoolss_q_open_printer_ex(&q_o, printername, datatype,
+ access_required, station, username);
- if (!spoolss_io_r_setform("", &r, &rbuf, 0))
- goto done;
+ /* turn parameters into data stream */
+ if (spoolss_io_q_open_printer_ex("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_OPENPRINTEREX, &buf, &rbuf))
+ {
+ SPOOL_R_OPEN_PRINTER_EX r_o;
+ BOOL p = True;
- /* Return output parameters */
+ spoolss_io_r_open_printer_ex("", &r_o, &rbuf, 0);
- result = r.status;
+ if (prs_offset(&rbuf)!= 0 && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(3,("SPOOLSS_OPENPRINTEREX: %s\n", nt_errstr(r_o.status)));
+ p = False;
+ }
- if (!W_ERROR_IS_OK(result))
- goto done;
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.handle;
+ /* associate the handle returned with the current
+ state of the clienjt connection */
+ valid_pol = RpcHndList_set_connection(hnd, con);
+ }
+ }
- done:
- prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
- return result;
+ return valid_pol;
}
-/** Get a form on a printer.
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param handle Policy handle opened with cli_spoolss_open_printer_ex
- * or cli_spoolss_addprinterex.
- * @param formname Name of the form to get
- * @param level Form info level to get - should always be 1.
- *
- */
-
-WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *handle, char *formname, uint32 level,
- FORM_1 *form)
+/****************************************************************************
+ do a SPOOLSS AddPrinterEx()
+ **ALWAYS** uses as PRINTER_INFO level 2 struct
+****************************************************************************/
+BOOL spoolss_addprinterex(POLICY_HND *hnd, const char* srv_name, PRINTER_INFO_2 *info2)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETFORM q;
- SPOOL_R_GETFORM r;
- WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ADDPRINTEREX q_o;
+ SPOOL_R_ADDPRINTEREX r_o;
+ struct cli_connection *con = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+ fstring the_client_name;
+ BOOL valid_pol = True;
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
- /* Initialise parse structures */
- init_buffer(&buffer, offered, mem_ctx);
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ return NT_STATUS_ACCESS_DENIED;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ if (hnd == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
- /* Initialise input parameters */
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("spoolss_addprinterex: talloc_init() failed!\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- make_spoolss_q_getform(&q, handle, formname, level, &buffer, offered);
+ /* create and send a MSRPC command with api SPOOLSS_ENUMPORTS */
+ DEBUG(5,("SPOOLSS Add Printer Ex (Server: %s)\n", srv_name));
- /* Marshall data and send request */
-
- if (!spoolss_io_q_getform("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_getform("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (W_ERROR_IS_OK(result))
- smb_io_form_1("", r.buffer, form, 0);
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-/** Delete a form on a printer.
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param handle Policy handle opened with cli_spoolss_open_printer_ex
- * or cli_spoolss_addprinterex.
- * @param form The name of the form to delete.
- *
- */
-
-WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *handle, char *form_name)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_DELETEFORM q;
- SPOOL_R_DELETEFORM 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_deleteform(&q, handle, form_name);
+ fstrcpy(the_client_name, "\\\\");
+ fstrcat(the_client_name, con->pCli_state->desthost);
+ strupper(the_client_name);
- /* Marshall data and send request */
-
- if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_deleteform("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
-
-static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
- uint32 num_forms, FORM_1 **forms)
-{
- int i;
-
- *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1));
- buffer->prs.data_offset = 0;
-
- for (i = 0; i < num_forms; i++)
- smb_io_form_1("", buffer, &((*forms)[i]), 0);
-}
-
-/** Enumerate forms
- *
- * @param cli Pointer to client state structure which is open
- * on the SPOOLSS pipe.
- * @param mem_ctx Pointer to an initialised talloc context.
- *
- * @param offered Buffer size offered in the request.
- * @param needed Number of bytes needed to complete the request.
- * may be NULL.
- * or cli_spoolss_addprinterex.
- * @param level Form info level to get - should always be 1.
- * @param handle Open policy handle
- *
- */
-
-WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *handle, int level, uint32 *num_forms,
- FORM_1 **forms)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ENUMFORMS q;
- SPOOL_R_ENUMFORMS 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_enumforms(&q, handle, level, &buffer, offered);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_enumforms("", &r, &rbuf, 0))
- goto done;
-
- /* Return output parameters */
-
- result = r.status;
-
- if (needed)
- *needed = r.needed;
-
- if (num_forms)
- *num_forms = r.numofforms;
-
- decode_forms_1(mem_ctx, r.buffer, *num_forms, forms);
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- 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));
- buffer->prs.data_offset = 0;
+ make_spoolss_q_addprinterex(mem_ctx, &q_o, srv_name, the_client_name,
+ /* "Administrator", */
+ con->pCli_state->user_name,
+ 2, info2);
+
+ /* turn parameters into data stream and send the request */
+ if (spoolss_io_q_addprinterex("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_ADDPRINTEREX, &buf, &rbuf))
+ {
+ ZERO_STRUCT(r_o);
+
+ if(spoolss_io_r_addprinterex("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ /* report error code */
+ DEBUG(3,("SPOOLSS_ADDPRINTEREX: %s\n", nt_errstr(r_o.status)));
+ valid_pol = False;
+ }
+ }
+
+ if (valid_pol)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ copy_policy_hnd( hnd, &r_o.handle);
+
+ /* associate the handle returned with the current
+ state of the clienjt connection */
+ RpcHndList_set_connection(hnd, con);
+ }
+ }
- 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;
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2));
- buffer->prs.data_offset = 0;
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
- for (i = 0; i < num_jobs; i++)
- smb_io_job_info_2("", buffer, &((*jobs)[i]), 0);
+ return valid_pol;
}
-/* 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)
+/****************************************************************************
+do a SPOOL Close
+****************************************************************************/
+BOOL spoolss_closeprinter(POLICY_HND *hnd)
{
- 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;
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_CLOSEPRINTER q_c;
+ BOOL valid_close = False;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ if (hnd == NULL)
+ return False;
+
+ /* create and send a MSRPC command with api SPOOLSS_CLOSEPRINTER */
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
+ return False;
}
+ prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
+ DEBUG(4,("SPOOL Close Printer\n"));
-/* 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);
+ /* store the parameters */
+ make_spoolss_q_closeprinter(&q_c, hnd);
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ /* turn parameters into data stream */
+ if (spoolss_io_q_closeprinter("", &q_c, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, SPOOLSS_CLOSEPRINTER, &buf, &rbuf))
+ {
+ SPOOL_R_CLOSEPRINTER r_c;
- /* Initialise parse structures */
+ spoolss_io_r_closeprinter("", &r_c, &rbuf, 0);
- 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 */
+ if (prs_offset(&rbuf)!=0 && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(3,("SPOOL_CLOSEPRINTER: %s\n", nt_errstr(r_c.status)));
+ }
+ else
+ valid_close = True;
+ }
- result = r.status;
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ /* disassociate with the cli_connection */
+ RpcHndList_del_connection(hnd);
- return result;
+ return valid_close;
}
-/* 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)
+/****************************************************************************
+do a SPOOLSS Get printer datas
+****************************************************************************/
+uint32 spoolss_getprinterdata(const POLICY_HND *hnd, const UNISTR2 *valuename,
+ uint32 in_size,
+ uint32 *type,
+ uint32 *out_size,
+ uint8 *data,
+ uint32 *needed)
{
- 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;
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_GETPRINTERDATA q_o;
+ SPOOL_R_GETPRINTERDATA r_o;
+ TALLOC_CTX *mem_ctx = NULL;
- /* Unmarshall response */
+ if (hnd == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
- 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;
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
+ return False;
}
+ prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
+ /* create and send a MSRPC command with api SPOOLSS_GETPRINTERDATA */
-/* Startpageprinter. Sent to notify the spooler when a page is about to be
- sent to a printer. */
+ DEBUG(5,("SPOOLSS Get Printer data)\n"));
-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);
+ make_spoolss_q_getprinterdata(&q_o, hnd,(UNISTR2 *)valuename, in_size);
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ /* turn parameters into data stream */
+ if (spoolss_io_q_getprinterdata("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, SPOOLSS_GETPRINTERDATA, &buf, &rbuf))
+ {
+ ZERO_STRUCT(r_o);
+ prs_mem_free(&buf );
- /* Initialise parse structures */
+ r_o.data=data;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ if(spoolss_io_r_getprinterdata("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ DEBUG(3,("SPOOLSS_GETPRINTERDATA: %s\n", nt_errstr(r_o.status)));
+ }
- /* 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;
+ *type=r_o.type;
+ *out_size=r_o.size;
+ *needed=r_o.needed;
+ }
+ }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- return result;
+ return r_o.status;
}
-/* Get printer data */
-
-WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered, uint32 *needed,
- POLICY_HND *hnd, char *valuename,
- uint32 *data_type, char **data,
- uint32 *data_size)
+/****************************************************************************
+do a SPOOLSS Get Printer Driver Direcotry
+****************************************************************************/
+uint32 spoolss_getprinterdriverdir(fstring srv_name, fstring env_name, uint32 level,
+ NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed)
{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTERDATA q;
- SPOOL_R_GETPRINTERDATA r;
- WERROR result = W_ERROR(ERRgeneral);
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_GETPRINTERDRIVERDIR q_o;
+ SPOOL_R_GETPRINTERDRIVERDIR r_o;
+ TALLOC_CTX *ctx = prs_get_mem_context(&buffer->prs);
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
+ struct cli_connection *con = NULL;
- /* Initialise parse structures */
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ return False;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ prs_init(&buf, MAX_PDU_FRAG_LEN, ctx, MARSHALL);
+ prs_init(&rbuf, 0, ctx, UNMARSHALL);
- /* Initialise input parameters */
+ /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
- make_spoolss_q_getprinterdata(&q, hnd, valuename, offered);
+ DEBUG(5,("SPOOLSS GetPrinterDriverDir (Server: %s Env: %s level: %d)\n",
+ srv_name, env_name, level));
- /* Marshall data and send request */
+ make_spoolss_q_getprinterdriverdir(&q_o, srv_name, env_name, level,
+ buffer, offered);
- if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf))
- goto done;
+ /* turn parameters into data stream */
+ if (spoolss_io_q_getprinterdriverdir("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_GETPRINTERDRIVERDIRECTORY, &buf, &rbuf))
+ {
+ prs_mem_free(&buf );
+ ZERO_STRUCT(r_o);
- /* Unmarshall response */
+ prs_switch_type(&buffer->prs, UNMARSHALL);
+ prs_set_offset(&buffer->prs, 0);
+ r_o.buffer=buffer;
- 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 */
-
- if (data_type)
- *data_type = r.type;
+ if(spoolss_io_r_getprinterdriverdir("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ DEBUG(3,("SPOOLSS_GETPRINTERDRIVERDIRECTORY: %s\n", nt_errstr(r_o.status)));
+ }
- if (data) {
- *data = (char *)talloc(mem_ctx, r.needed);
- memcpy(*data, r.data, r.needed);
+ *needed=r_o.needed;
+ }
}
- if (data_size)
- *data_size = r.needed;
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ cli_connection_unlink(con);
- return result;
+ return r_o.status;
}
-/* Set printer data */
-
-WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, char *value,
- uint32 data_type, char *data,
- uint32 data_size)
+/******************************************************************************
+ AddPrinterDriver()
+ *****************************************************************************/
+uint32 spoolss_addprinterdriver(const char *srv_name, uint32 level, PRINTER_DRIVER_CTR *info)
{
- 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, data, data_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;
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ADDPRINTERDRIVER q_o;
+ SPOOL_R_ADDPRINTERDRIVER r_o;
+ TALLOC_CTX *mem_ctx = NULL;
+ struct cli_connection *con = NULL;
- 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,
- char **value, uint32 *data_type, char **data,
- uint32 *data_size)
-{
- 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);
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ return False;
- /* 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 (data_type)
- *data_type = r.type;
-
- if (value) {
- fstring the_value;
-
- rpcstr_pull(the_value, r.value, sizeof(the_value), -1,
- STR_TERMINATE);
-
- *value = talloc_strdup(mem_ctx, the_value);
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
+ return False;
}
-
- if (data)
- *data = talloc_memdup(mem_ctx, r.data, r.realdatasize);
-
- if (data_size)
- *data_size = r.realdatasize;
-
- 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);
-
- /* Marshall data and send request */
-
- if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0))
- goto done;
+ prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- 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;
+ /* make the ADDPRINTERDRIVER PDU */
+ make_spoolss_q_addprinterdriver(mem_ctx, &q_o, srv_name, level, info);
+
+ /* turn the data into an io stream */
+ if (spoolss_io_q_addprinterdriver("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_ADDPRINTERDRIVER, &buf, &rbuf))
+ {
+ ZERO_STRUCT(r_o);
+
+ if(spoolss_io_r_addprinterdriver("", &r_o, &rbuf, 0))
+ {
+ if (r_o.status != NT_STATUS_OK)
+ {
+ /* report error code */
+ DEBUG(3,("SPOOLSS_ADDPRINTERDRIVER: %s\n", nt_errstr(r_o.status)));
+ }
+ }
+ }
- /* Unmarshall response */
- if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return r_o.status;
- return result;
}
-
-/** @} **/
diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c
index f03046558e..320708736e 100644
--- a/source3/rpc_client/cli_spoolss_notify.c
+++ b/source3/rpc_client/cli_spoolss_notify.c
@@ -1,119 +1,260 @@
-/*
- 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;
+ 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));
+ 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 & 1)) {
+ 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,
- 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;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0))
+ }
+
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYOPENPRINTER, &buf, &rbuf))
goto done;
-
- /* Return result */
- memcpy(handle, &r.handle, sizeof(r.handle));
- result = r.status;
+ /* 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;
+ }
+
+ 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 );
- make_spoolss_q_reply_closeprinter(&q, handle);
+ /* create and send a MSRPC command with api */
+
+ /* store the parameters */
+ make_spoolss_q_reply_closeprinter(&q_s, handle);
- /* Marshall data and send request */
+ /* 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;
+ }
- if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf))
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYCLOSEPRINTER, &buf, &rbuf))
goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0))
+
+ /* 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;
-
- /* Return result */
+ }
+
- result = r.status;
+ result = r_s.status;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ 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,147 +262,186 @@ 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;
-
+ }
+
+
+ if (!rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
+ goto done;
+
/* Unmarshall response */
-
- if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0))
+ 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:
prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ prs_mem_free(&rbuf);
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);
+ make_spoolss_q_reply_rrpcn(&q_s, handle, info->low, info->high, &notify_info);
- /* Marshall data and send request */
+ /* 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;
+ }
- if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf))
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &buf, &rbuf))
goto done;
- /* Unmarshall response */
- if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0))
+ /* 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;
+ }
- if (r.unknown0 == 0x00080000)
+ 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;
}
-WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 flags, uint32 options,
- 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))
- goto done;
-
- /* Unmarshall response */
-
- if(!spoolss_io_r_rffpcnex("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
diff --git a/source3/rpc_client/cli_srvsvc.c b/source3/rpc_client/cli_srvsvc.c
index 1bdd19620b..06e733893e 100644
--- a/source3/rpc_client/cli_srvsvc.c
+++ b/source3/rpc_client/cli_srvsvc.c
@@ -1,445 +1,404 @@
/*
- 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 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.
-*/
+ * 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 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"
-NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 switch_value, SRV_INFO_CTR *ctr)
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
+
+/****************************************************************************
+do a server net conn enum
+****************************************************************************/
+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)
{
- 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 */
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_CONN_ENUM q_o;
+ SRV_R_NET_CONN_ENUM r_o;
+
+ if (server_name == NULL || ctr == NULL || preferred_len == 0)
+ return False;
+
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api SRV_NET_CONN_ENUM */
+
+ DEBUG(4,("SRV Net Server Connection Enum(%s, %s), level %d, enum:%8x\n",
+ server_name, qual_name, switch_value, get_enum_hnd(hnd)));
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_conn_ctr = 1;
+ ctr->conn.info0.num_entries_read = 0;
+ ctr->conn.info0.ptr_conn_info = 1;
+
+ /* store the parameters */
+ init_srv_q_net_conn_enum(&q_o, server_name, qual_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
+
+ /* turn parameters into data stream */
+ if(!srv_io_q_net_conn_enum("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- 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;
+ /* send the data on \PIPE\ */
+ if(!rpc_api_pipe_req(cli, SRV_NET_CONN_ENUM, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- /* Unmarshall response */
+ prs_mem_free(&data);
- r.ctr = ctr;
+ r_o.ctr = ctr;
- if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
+ if(!srv_io_r_net_conn_enum("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
}
- result = werror_to_ntstatus(r.status);
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
+ }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ if (r_o.ctr->switch_value != switch_value) {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ prs_mem_free(&rdata);
+ return False;
+ }
- return result;
+ prs_mem_free(&rdata);
+
+ return True;
}
-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 */
+/****************************************************************************
+do a server net sess enum
+****************************************************************************/
- memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1,
- sizeof(SH_INFO_1));
+BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ char *user_name,
+ uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_SESS_ENUM q_o;
+ SRV_R_NET_SESS_ENUM r_o;
+
+ if (server_name == NULL || ctr == NULL || preferred_len == 0)
+ return False;
+
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api SRV_NET_SESS_ENUM */
+
+ DEBUG(4,("SRV Net Session Enum (%s), level %d, enum:%8x\n",
+ server_name, switch_value, get_enum_hnd(hnd)));
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_sess_ctr = 1;
+ ctr->sess.info0.num_entries_read = 0;
+ ctr->sess.info0.ptr_sess_info = 1;
+
+ /* store the parameters */
+ init_srv_q_net_sess_enum(&q_o, server_name, qual_name, user_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
+
+ /* turn parameters into data stream */
+ if(!srv_io_q_net_sess_enum("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- /* Duplicate strings */
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SRV_NET_SESS_ENUM, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- 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, strlen(s) + 1);
-
- 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, strlen(s) + 1);
+ prs_mem_free(&data);
- }
+ r_o.ctr = ctr;
- break;
- case 2:
- ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc(
- mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries);
+ if(!srv_io_r_net_sess_enum("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
+ }
- 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, strlen(s) + 1);
-
- 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, strlen(s) + 1);
-
- 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, strlen(s) + 1);
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
+ }
- 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, strlen(s) + 1);
- }
- break;
+ if (r_o.ctr->switch_value != switch_value) {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ prs_mem_free(&rdata);
+ return False;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
- return result;
+ prs_mem_free(&rdata);
+
+ return True;
}
-WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *sharename)
+/****************************************************************************
+do a server net share enum
+****************************************************************************/
+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)
{
- 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;
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_SHARE_ENUM q_o;
+
+ if (server_name == NULL || preferred_len == 0)
+ return False;
+
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api SRV_NET_SHARE_ENUM */
+
+ DEBUG(4,("SRV Get Share Info (%s), level %d, enum:%8x\n",
+ server_name, switch_value, get_enum_hnd(hnd)));
+
+ /* store the parameters */
+ init_srv_q_net_share_enum(&q_o, server_name, switch_value,
+ preferred_len, hnd);
+
+ /* turn parameters into data stream */
+ if(!srv_io_q_net_share_enum("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- /* Unmarshall response */
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- if (!srv_io_r_net_share_del("", &r, &rbuf, 0))
- goto done;
+ prs_mem_free(&data);
- result = r.status;
+ if(!srv_io_r_net_share_enum("", r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
+ }
+
+ if (r_o->status != 0) {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SHARE_ENUM: %s\n", nt_errstr(r_o->status)));
+ prs_mem_free(&rdata);
+ return False;
+ }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ if (r_o->ctr.switch_value != switch_value) {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SHARE_ENUM: info class %d does not match request %d\n",
+ r_o->ctr.switch_value, switch_value));
+ prs_mem_free(&rdata);
+ return False;
+ }
- return result;
+ prs_mem_free(&rdata);
+
+ return True;
}
-WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- char *netname, uint32 type, char *remark,
- uint32 perms, uint32 max_uses, uint32 num_uses,
- char *path, 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);
+/****************************************************************************
+do a server net file enum
+****************************************************************************/
- /* 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)
+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)
{
- 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 */
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_FILE_ENUM q_o;
+ SRV_R_NET_FILE_ENUM r_o;
+
+ if (server_name == NULL || ctr == NULL || preferred_len == 0)
+ return False;
+
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api SRV_NET_FILE_ENUM */
+
+ DEBUG(4,("SRV Get File Info (%s), level %d, enum:%8x\n",
+ server_name, switch_value, get_enum_hnd(hnd)));
+
+ q_o.file_level = switch_value;
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_file_ctr = 1;
+ ctr->file.info3.num_entries_read = 0;
+ ctr->file.info3.ptr_file_info = 1;
+
+ /* store the parameters */
+ init_srv_q_net_file_enum(&q_o, server_name, qual_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
+
+ /* turn parameters into data stream */
+ if(!srv_io_q_net_file_enum("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- r.tod = tod;
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0))
- goto done;
+ prs_mem_free(&data);
- result = r.status;
+ r_o.ctr = ctr;
- if (!W_ERROR_IS_OK(result))
- goto done;
+ if(!srv_io_r_net_file_enum("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
+ }
+
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_FILE_ENUM: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
+ }
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ if (r_o.ctr->switch_value != switch_value) {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_FILE_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ prs_mem_free(&rdata);
+ return False;
+ }
- return result;
+ prs_mem_free(&rdata);
+
+ return True;
}
-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)
+/****************************************************************************
+do a server get info
+****************************************************************************/
+BOOL do_srv_net_srv_get_info(struct cli_state *cli,
+ char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr)
{
- 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);
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_SRV_GET_INFO q_o;
+ SRV_R_NET_SRV_GET_INFO r_o;
- /* Initialise input parameters */
+ if (server_name == NULL || switch_value == 0 || ctr == NULL)
+ return False;
- init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name,
- file_level, ctr, preferred_len, hnd);
+ prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
- /* Marshall data and send request */
+ /* create and send a MSRPC command with api SRV_NET_SRV_GET_INFO */
- if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf))
- goto done;
+ DEBUG(4,("SRV Get Server Info (%s), level %d\n", server_name, switch_value));
- /* Unmarshall response */
+ /* store the parameters */
+ init_srv_q_net_srv_get_info(&q_o, server_name, switch_value);
- 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, strlen(s) + 1);
-
- 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, strlen(s) + 1);
-
- }
-
- break;
+ /* turn parameters into data stream */
+ if(!srv_io_q_net_srv_get_info("", &q_o, &data, 0)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
}
- 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 */
+ /* send the data on \PIPE\ */
+ if (!rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &data, &rdata)) {
+ prs_mem_free(&data);
+ prs_mem_free(&rdata);
+ return False;
+ }
- init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id);
+ prs_mem_free(&data);
- /* Marshall data and send request */
+ r_o.ctr = ctr;
- if (!srv_io_q_net_file_close("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf))
- goto done;
+ if(!srv_io_r_net_srv_get_info("", &r_o, &rdata, 0)) {
+ prs_mem_free(&rdata);
+ return False;
+ }
- /* Unmarshall response */
+ if (r_o.status != 0) {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", nt_errstr(r_o.status)));
+ prs_mem_free(&rdata);
+ return False;
+ }
- if (!srv_io_r_net_file_close("", &r, &rbuf, 0))
- goto done;
+ if (r_o.ctr->switch_value != q_o.switch_value) {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, q_o.switch_value));
+ prs_mem_free(&rdata);
+ return False;
+ }
- result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
- return result;
+ prs_mem_free(&rdata);
+
+ return True;
}
diff --git a/source3/rpc_client/cli_wkssvc.c b/source3/rpc_client/cli_wkssvc.c
index 97b948bf62..90269dfbee 100644
--- a/source3/rpc_client/cli_wkssvc.c
+++ b/source3/rpc_client/cli_wkssvc.c
@@ -1,93 +1,87 @@
/*
- 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.
-*/
+ * 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 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"
-/**
- * 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)
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
+
+/****************************************************************************
+do a WKS Open Policy
+****************************************************************************/
+BOOL do_wks_query_info(struct cli_state *cli,
+ char *server_name, uint32 switch_value,
+ WKS_INFO_100 *wks100)
{
- prs_struct buf;
prs_struct rbuf;
+ prs_struct buf;
WKS_Q_QUERY_INFO q_o;
WKS_R_QUERY_INFO r_o;
- if (cli == NULL || wks100 == NULL)
- return NT_STATUS_UNSUCCESSFUL;
+ if (server_name == 0 || wks100 == NULL)
+ return False;
+
+ prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL );
+
+ /* create and send a MSRPC command with api WKS_QUERY_INFO */
+
+ DEBUG(4,("WKS Query Info\n"));
- /* init rpc parse structures */
- prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ /* store the parameters */
+ init_wks_q_query_info(&q_o, server_name, switch_value);
- 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)) {
+ /* turn parameters into data stream */
+ if(!wks_io_q_query_info("", &q_o, &buf, 0)) {
prs_mem_free(&buf);
prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
+ return False;
}
-
- /* actual rpc call over \PIPE\wkssvc */
+
+ /* send the data on \PIPE\ */
if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) {
prs_mem_free(&buf);
prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
+ return False;
}
-
+
prs_mem_free(&buf);
r_o.wks100 = wks100;
- /* get call results from response buffer */
- if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) {
+ if(!wks_io_r_query_info("", &r_o, &rbuf, 0)) {
prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
+ return False;
}
-
- /* check returnet status code */
- if (NT_STATUS_IS_ERR(r_o.status)) {
- /* report the error */
+
+ if (r_o.status != 0) {
+ /* report error code */
DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status)));
prs_mem_free(&rbuf);
- return r_o.status;
+ return False;
}
-
- /* do clean up */
+
prs_mem_free(&rbuf);
-
- return NT_STATUS_OK;
-}
+ return True;
+}
diff --git a/source3/rpc_client/msrpc_spoolss.c b/source3/rpc_client/msrpc_spoolss.c
new file mode 100644
index 0000000000..56c70730ba
--- /dev/null
+++ b/source3/rpc_client/msrpc_spoolss.c
@@ -0,0 +1,812 @@
+/*
+ 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) 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.
+*/
+
+#include "includes.h"
+#include "nterr.h"
+#include "rpc_parse.h"
+#include "rpcclient.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
+
+#define DEBUG_TESTING
+
+extern FILE* out_hnd;
+
+extern struct user_creds *usr_creds;
+
+/********************************************************************
+initialize a spoolss NEW_BUFFER.
+********************************************************************/
+void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
+{
+ buffer->ptr = (size!=0)? 1:0;
+ buffer->size=size;
+ buffer->string_at_end=size;
+ prs_init(&buffer->prs, size, ctx, MARSHALL);
+ buffer->struct_start = prs_offset(&buffer->prs);
+}
+
+static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned,
+ PRINTER_INFO_0 **info)
+{
+ uint32 i;
+ PRINTER_INFO_0 *inf;
+
+ inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_0("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned,
+ PRINTER_INFO_1 **info)
+{
+ uint32 i;
+ PRINTER_INFO_1 *inf;
+
+ inf=(PRINTER_INFO_1 *)malloc(returned*sizeof(PRINTER_INFO_1));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned,
+ PRINTER_INFO_2 **info)
+{
+ uint32 i;
+ PRINTER_INFO_2 *inf;
+
+ inf=(PRINTER_INFO_2 *)malloc(returned*sizeof(PRINTER_INFO_2));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ /* a little initialization as we go */
+ inf[i].secdesc = NULL;
+ new_smb_io_printer_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned,
+ PRINTER_INFO_3 **info)
+{
+ uint32 i;
+ PRINTER_INFO_3 *inf;
+
+ inf=(PRINTER_INFO_3 *)malloc(returned*sizeof(PRINTER_INFO_3));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_3("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned,
+ DRIVER_INFO_1 **info)
+{
+ uint32 i;
+ DRIVER_INFO_1 *inf;
+
+ inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned,
+ DRIVER_INFO_2 **info)
+{
+ uint32 i;
+ DRIVER_INFO_2 *inf;
+
+ inf=(DRIVER_INFO_2 *)malloc(returned*sizeof(DRIVER_INFO_2));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_3(NEW_BUFFER *buffer, uint32 returned,
+ DRIVER_INFO_3 **info)
+{
+ uint32 i;
+ DRIVER_INFO_3 *inf;
+
+ inf=(DRIVER_INFO_3 *)malloc(returned*sizeof(DRIVER_INFO_3));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printerdriverdir_info_1(NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info)
+{
+/* DRIVER_DIRECTORY_1 *inf;
+
+ inf=(DRIVER_DIRECTORY_1 *)malloc(returned*sizeof(DRIVER_DIRECTORY_1));
+*/
+ prs_set_offset(&buffer->prs, 0);
+
+ new_smb_io_driverdir_1("", buffer, info, 0);
+
+/* *info=inf;*/
+}
+
+/**********************************************************************
+ Decode a PORT_INFO_1 struct from a NEW_BUFFER
+**********************************************************************/
+void decode_port_info_1(NEW_BUFFER *buffer, uint32 returned,
+ PORT_INFO_1 **info)
+{
+ uint32 i;
+ PORT_INFO_1 *inf;
+
+ inf=(PORT_INFO_1*)malloc(returned*sizeof(PORT_INFO_1));
+
+ prs_set_offset(&buffer->prs, 0);
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_port_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+ Decode a PORT_INFO_2 struct from a NEW_BUFFER
+**********************************************************************/
+void decode_port_info_2(NEW_BUFFER *buffer, uint32 returned,
+ PORT_INFO_2 **info)
+{
+ uint32 i;
+ PORT_INFO_2 *inf;
+
+ inf=(PORT_INFO_2*)malloc(returned*sizeof(PORT_INFO_2));
+
+ prs_set_offset(&buffer->prs, 0);
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_port_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_printers(char* srv_name, uint32 flags,
+ uint32 level, PRINTER_INFO_CTR ctr)
+{
+ NTSTATUS status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_printers: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+
+ /* send a NULL buffer first */
+ status=spoolss_enum_printers(flags, srv_name, level, &buffer, 0,
+ &needed, &returned);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status=spoolss_enum_printers(flags, srv_name, level, &buffer,
+ needed, &needed, &returned);
+ }
+
+ if (status!=NT_STATUS_OK)
+ {
+ DEBUG(0,("spoolss_enum_printers: %s\n", nt_errstr(status)));
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ /* is there anything to process? */
+ if (returned != 0)
+ {
+ switch (level) {
+ case 1:
+ decode_printer_info_1(&buffer, returned, &(ctr.printers_1));
+ break;
+ case 2:
+ decode_printer_info_2(&buffer, returned, &(ctr.printers_2));
+ break;
+ case 3:
+ decode_printer_info_3(&buffer, returned, &(ctr.printers_3));
+ break;
+ }
+
+ display_printer_info_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
+ }
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_ports(char* srv_name,
+ uint32 level, PORT_INFO_CTR *ctr)
+{
+ NTSTATUS status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_ports: talloc_init failed!\n"));
+ return False;
+ }
+
+ init_buffer(&buffer, 0, mem_ctx);
+
+ /* send a NULL buffer first */
+ status=spoolss_enum_ports(srv_name, level, &buffer, 0,
+ &needed, &returned);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status=spoolss_enum_ports(srv_name, level, &buffer,
+ needed, &needed, &returned);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ /* is there anything to process? */
+ if (returned != 0)
+ {
+ switch (level) {
+ case 1:
+ decode_port_info_1(&buffer, returned, &ctr->port.info_1);
+ break;
+ case 2:
+ decode_port_info_2(&buffer, returned, &ctr->port.info_2);
+ break;
+ default:
+ DEBUG(0,("Unable to decode unknown PORT_INFO_%d\n", level));
+ break;
+ }
+
+ display_port_info_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
+ display_port_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
+ display_port_info_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
+ }
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+uint32 msrpc_spoolss_getprinterdata( const char* printer_name,
+ const char* station,
+ const char* user_name,
+ const char* value_name,
+ uint32 *type,
+ NEW_BUFFER *buffer,
+ void *fn)
+{
+ POLICY_HND hnd;
+ NTSTATUS status;
+ uint32 needed;
+ uint32 size;
+ char *data;
+ UNISTR2 uni_val_name;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("spoolgetdata - printer: %s server: %s user: %s value: %s\n",
+ printer_name, station, user_name, value_name));
+
+ if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name,
+ &hnd))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ init_unistr2(&uni_val_name, value_name, 0);
+ size = 0;
+ data = NULL;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_getprinterdata: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(buffer, size, mem_ctx);
+
+ status = spoolss_getprinterdata(&hnd, &uni_val_name, size, type, &size,
+ (unsigned char *)data, &needed);
+
+ if (status == ERROR_INSUFFICIENT_BUFFER)
+ {
+ size = needed;
+ init_buffer(buffer, size, mem_ctx);
+ data = prs_data_p(&buffer->prs);
+ status = spoolss_getprinterdata(&hnd, &uni_val_name,
+ size, type, &size,
+ (unsigned char *)data, &needed);
+ }
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ if (status != NT_STATUS_OK)
+ {
+ if (!spoolss_closeprinter(&hnd))
+ return NT_STATUS_ACCESS_DENIED;
+ return status;
+ }
+
+#if 0
+ if (fn != NULL)
+ fn(printer_name, station, level, returned, *ctr);
+#endif
+
+ return status;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_jobs( const char* printer_name,
+ const char* station, const char* user_name,
+ uint32 level,
+ void ***ctr, JOB_INFO_FN(fn))
+{
+ POLICY_HND hnd;
+ NTSTATUS status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ uint32 firstjob=0;
+ uint32 numofjobs=0xffff;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
+ printer_name, station, user_name));
+
+ if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name, &hnd))
+ return False;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+ status = spoolss_enum_jobs(&hnd, firstjob, numofjobs, level,
+ &buffer, 0, &needed, &returned);
+
+ if (status == ERROR_INSUFFICIENT_BUFFER)
+ {
+ init_buffer(&buffer, needed, mem_ctx);
+ status = spoolss_enum_jobs( &hnd, firstjob, numofjobs, level,
+ &buffer, needed, &needed, &returned);
+ }
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ if (status!=NT_STATUS_OK) {
+ if (!spoolss_closeprinter(&hnd))
+ return False;
+ return False;
+ }
+
+ if (fn != NULL)
+ fn(printer_name, station, level, returned, *ctr);
+
+ return True;
+}
+
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_printerdata( const char* printer_name,
+ const char* station, const char* user_name )
+{
+ POLICY_HND hnd;
+ NTSTATUS status;
+ uint32 idx;
+ uint32 valuelen;
+ uint16 *value;
+ uint32 rvaluelen;
+ uint32 type;
+ uint32 datalen;
+ uint8 *data;
+ uint32 rdatalen;
+ uint32 maxvaluelen;
+ uint32 maxdatalen;
+
+ DEBUG(4,("msrpc_spoolss_enum_printerdata - printer: %s\n", printer_name));
+
+ if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name, &hnd))
+ return False;
+
+
+ idx=0;
+ valuelen=0;
+ rvaluelen=0;
+ type=0;
+ datalen=0;
+ rdatalen=0;
+
+ status = spoolss_enum_printerdata(&hnd, idx, &valuelen, value,
+ &rvaluelen, &type, &datalen,
+ data, &rdatalen);
+
+ DEBUG(4,("spoolenum_printerdata - got size: biggest value:[%d], biggest data:[%d]\n", rvaluelen, rdatalen));
+
+ maxvaluelen=valuelen=rvaluelen;
+ maxdatalen=datalen=rdatalen;
+
+ value=(uint16 *)malloc(valuelen*sizeof(uint16));
+ data=(uint8 *)malloc(datalen*sizeof(uint8));
+
+ display_printer_enumdata(out_hnd, ACTION_HEADER, idx, valuelen,
+ value, rvaluelen, type, datalen, data, rdatalen);
+
+ do {
+ valuelen=maxvaluelen;
+ datalen=maxdatalen;
+
+ status = spoolss_enum_printerdata(&hnd, idx, &valuelen,
+ value, &rvaluelen, &type,
+ &datalen, data, &rdatalen);
+ display_printer_enumdata(out_hnd, ACTION_ENUMERATE, idx,
+ valuelen, value, rvaluelen, type,
+ datalen, data, rdatalen);
+ idx++;
+
+ } while (status != 0x0103); /* NO_MORE_ITEMS */
+
+ display_printer_enumdata(out_hnd, ACTION_FOOTER, idx, valuelen,
+ value, rvaluelen, type, datalen, data, rdatalen);
+
+
+ if (status!=NT_STATUS_OK) {
+ /*
+ * the check on this if statement is redundant
+ * since is the status is bad we're going to
+ * return False anyways. The caller will be
+ * unable to determine if there really was a problem
+ * with the spoolss_closeprinter() call --jerry
+ */
+ spoolss_closeprinter(&hnd);
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_getprinter( const char* printer_name, const uint32 level,
+ const char* station, const char* user_name,
+ PRINTER_INFO_CTR ctr)
+{
+ POLICY_HND hnd;
+ NTSTATUS status=0;
+ NEW_BUFFER buffer;
+ uint32 needed=1000;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("spoolenum_getprinter - printer: %s\n", printer_name));
+
+ if(!spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, station, user_name, &hnd))
+ return False;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_getprinter: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, needed, mem_ctx);
+
+ status = spoolss_getprinter(&hnd, level, &buffer, needed, &needed);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status = spoolss_getprinter(&hnd, level, &buffer, needed, &needed);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ switch (level) {
+ case 0:
+ decode_printer_info_0(&buffer, 1, &(ctr.printers_0));
+ break;
+ case 1:
+ decode_printer_info_1(&buffer, 1, &(ctr.printers_1));
+ break;
+ case 2:
+ decode_printer_info_2(&buffer, 1, &(ctr.printers_2));
+ break;
+ case 3:
+ decode_printer_info_3(&buffer, 1, &(ctr.printers_3));
+ break;
+ }
+
+ display_printer_info_ctr(out_hnd, ACTION_HEADER , level, 1, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, 1, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_FOOTER , level, 1, ctr);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ if (status!=NT_STATUS_OK) {
+ if (!spoolss_closeprinter(&hnd))
+ return False;
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_getprinterdriver( const char* printer_name,
+ const char *environment, const uint32 level,
+ const char* station, const char* user_name,
+ PRINTER_DRIVER_CTR ctr)
+{
+ POLICY_HND hnd;
+ NTSTATUS status=0;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("msrpc_spoolss_enum_getprinterdriver - printer: %s\n", printer_name));
+
+ if(!spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, station, user_name, &hnd))
+ return False;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_getprinterdriver: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+
+ status = spoolss_getprinterdriver(&hnd, environment, level, &buffer, 0, &needed);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status = spoolss_getprinterdriver(&hnd, environment, level, &buffer, needed, &needed);
+ }
+
+ /* report(out_hnd, "\tstatus:[%d (%x)]\n", status, status); */
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ switch (level) {
+ case 1:
+ decode_printer_driver_1(&buffer, 1, &(ctr.info1));
+ break;
+ case 2:
+ decode_printer_driver_2(&buffer, 1, &(ctr.info2));
+ break;
+ case 3:
+ decode_printer_driver_3(&buffer, 1, &(ctr.info3));
+ break;
+ }
+
+ display_printer_driver_ctr(out_hnd, ACTION_HEADER , level, 1, ctr);
+ display_printer_driver_ctr(out_hnd, ACTION_ENUMERATE, level, 1, ctr);
+ display_printer_driver_ctr(out_hnd, ACTION_FOOTER , level, 1, ctr);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ if (status!=NT_STATUS_OK) {
+ if (!spoolss_closeprinter(&hnd))
+ return False;
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enumprinterdrivers( const char* srv_name,
+ const char *environment, const uint32 level,
+ PRINTER_DRIVER_CTR ctr)
+{
+ NTSTATUS status=0;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("msrpc_spoolss_enum_enumprinterdrivers - server: %s\n", srv_name));
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enumprinterdrivers: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+
+ status = spoolss_enum_printerdrivers(srv_name, environment,
+ level, &buffer, 0, &needed, &returned);
+
+ if (status == ERROR_INSUFFICIENT_BUFFER)
+ {
+ init_buffer(&buffer, needed, mem_ctx);
+ status = spoolss_enum_printerdrivers( srv_name, environment,
+ level, &buffer, needed, &needed, &returned);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ switch (level)
+ {
+ case 1:
+ decode_printer_driver_1(&buffer, returned, &(ctr.info1));
+ break;
+ case 2:
+ decode_printer_driver_2(&buffer, returned, &(ctr.info2));
+ break;
+ case 3:
+ decode_printer_driver_3(&buffer, returned, &(ctr.info3));
+ break;
+ }
+
+ display_printer_driver_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
+ display_printer_driver_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
+ display_printer_driver_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_getprinterdriverdir(char* srv_name, char* env_name, uint32 level, DRIVER_DIRECTORY_CTR ctr)
+{
+ NTSTATUS status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_getprinterdriverdir: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+
+ /* send a NULL buffer first */
+ status=spoolss_getprinterdriverdir(srv_name, env_name, level, &buffer, 0, &needed);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status=spoolss_getprinterdriverdir(srv_name, env_name, level, &buffer, needed, &needed);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ switch (level) {
+ case 1:
+ decode_printerdriverdir_info_1(&buffer, &(ctr.driver.info_1));
+ break;
+ }
+
+ display_printerdriverdir_info_ctr(out_hnd, ACTION_HEADER , level, ctr);
+ display_printerdriverdir_info_ctr(out_hnd, ACTION_ENUMERATE, level, ctr);
+ display_printerdriverdir_info_ctr(out_hnd, ACTION_FOOTER , level, ctr);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return True;
+}
diff --git a/source3/rpc_client/ntclienttrust.c b/source3/rpc_client/ntclienttrust.c
new file mode 100644
index 0000000000..284fd491f8
--- /dev/null
+++ b/source3/rpc_client/ntclienttrust.c
@@ -0,0 +1,157 @@
+/*
+ Unix SMB/CIFS implementation.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-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.
+*/
+
+#include "includes.h"
+
+
+/************************************************************************
+ check workstation trust account status
+ ************************************************************************/
+BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
+ char *hostname, char *domain, fstring mach_acct,
+ fstring new_mach_pwd)
+{
+ pstring tmp;
+ fstring mach_pwd;
+ struct cli_state cli_trust;
+ uchar lm_owf_mach_pwd[16];
+ uchar nt_owf_mach_pwd[16];
+ uchar lm_sess_pwd[24];
+ uchar nt_sess_pwd[24];
+
+ BOOL right_error_code = False;
+ uint8 err_cls;
+ uint32 err_num;
+
+ char *start_mach_pwd;
+ char *change_mach_pwd;
+
+ /* initial machine password */
+ fstrcpy(mach_pwd, hostname);
+ strlower(mach_pwd);
+
+ slprintf(tmp, sizeof(tmp) - 1,"Enter Workstation Trust Account password for [%s].\nDefault is [%s].\nPassword:",
+ mach_acct, mach_pwd);
+
+ start_mach_pwd = (char*)getpass(tmp);
+
+ if (start_mach_pwd[0] != 0)
+ {
+ fstrcpy(mach_pwd, start_mach_pwd);
+ }
+
+ slprintf(tmp, sizeof(tmp)-1, "Enter new Workstation Trust Account password for [%s]\nPress Return to leave at old value.\nNew Password:",
+ mach_acct);
+
+ change_mach_pwd = (char*)getpass(tmp);
+
+ if (change_mach_pwd[0] != 0)
+ {
+ fstrcpy(new_mach_pwd, change_mach_pwd);
+ }
+ else
+ {
+ DEBUG(1,("trust_account_check: password change not requested\n"));
+ change_mach_pwd[0] = 0;
+ }
+
+ DEBUG(1,("initialise cli_trust connection\n"));
+
+ if (!cli_initialise(&cli_trust))
+ {
+ DEBUG(1,("cli_initialise failed for cli_trust\n"));
+ return False;
+ }
+
+ DEBUG(1,("server connect for cli_trust\n"));
+
+ if (!server_connect_init(&cli_trust, hostname, dest_ip, dest_host))
+ {
+ cli_error(&cli_trust, &err_cls, &err_num, NULL);
+ DEBUG(1,("server_connect_init failed (%s)\n", cli_errstr(&cli_trust)));
+
+ cli_shutdown(&cli_trust);
+ return False;
+ }
+
+ DEBUG(1,("server connect cli_trust succeeded\n"));
+
+ nt_lm_owf_gen(mach_pwd, nt_owf_mach_pwd, lm_owf_mach_pwd);
+
+ DEBUG(5,("generating nt owf from initial machine pwd: %s\n", mach_pwd));
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("client cryptkey: "));
+ dump_data(100, cli_trust.cryptkey, sizeof(cli_trust.cryptkey));
+#endif
+
+ SMBencrypt(nt_owf_mach_pwd, cli_trust.cryptkey, nt_sess_pwd);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_owf_mach_pwd: "));
+ dump_data(100, nt_owf_mach_pwd, sizeof(lm_owf_mach_pwd));
+ DEBUG(100,("nt_sess_pwd: "));
+ dump_data(100, nt_sess_pwd, sizeof(nt_sess_pwd));
+#endif
+
+ SMBencrypt(lm_owf_mach_pwd, cli_trust.cryptkey, lm_sess_pwd);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("lm_owf_mach_pwd: "));
+ dump_data(100, lm_owf_mach_pwd, sizeof(lm_owf_mach_pwd));
+ DEBUG(100,("lm_sess_pwd: "));
+ dump_data(100, lm_sess_pwd, sizeof(lm_sess_pwd));
+#endif
+
+ right_error_code = False;
+
+ if (cli_session_setup(&cli_trust, mach_acct,
+ nt_owf_mach_pwd, sizeof(nt_owf_mach_pwd),
+ nt_owf_mach_pwd, sizeof(nt_owf_mach_pwd), domain))
+ {
+ DEBUG(0,("cli_session_setup: NO ERROR! AAAGH! BUG IN SERVER DETECTED!!!\n"));
+ cli_shutdown(&cli_trust);
+
+ return False;
+ }
+
+ cli_error(&cli_trust, &err_cls, &err_num, NULL);
+
+ if (err_num == (0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT))
+ {
+ DEBUG(1,("cli_send_tconX: valid workstation trust account exists\n"));
+ right_error_code = True;
+ }
+
+ if (err_num == (0xC0000000 | NT_STATUS_NO_SUCH_USER))
+ {
+ DEBUG(1,("cli_send_tconX: workstation trust account does not exist\n"));
+ right_error_code = False;
+ }
+
+ if (!right_error_code)
+ {
+ DEBUG(1,("server_validate failed (%s)\n", cli_errstr(&cli_trust)));
+ }
+
+ cli_shutdown(&cli_trust);
+ return right_error_code;
+}
diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c
index 375bbd31d7..a6aecb7967 100644
--- a/source3/rpc_parse/parse_lsa.c
+++ b/source3/rpc_parse/parse_lsa.c
@@ -3,9 +3,8 @@
* 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 2002.
+ * Copyright (C) Paul Ashton 1997.
+ * 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
@@ -2118,121 +2117,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(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 (!prs_uint8s(False, "dom_guid", ps, depth, info->dom_guid.info, GUID_SIZE))
- 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(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(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;
-}
diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c
index da49a6531d..46fdce63ff 100644
--- a/source3/rpc_parse/parse_net.c
+++ b/source3/rpc_parse/parse_net.c
@@ -1335,7 +1335,7 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
********************************************************************/
BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
- int depth, uint16 validation_level)
+ int depth, uint16 validation_level)
{
int i;
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 4de6b88e9c..2ab8c7246e 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -893,11 +893,9 @@ BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *
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;
diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c
index 365ad2dc70..1ebc1532f3 100644
--- a/source3/rpc_parse/parse_reg.c
+++ b/source3/rpc_parse/parse_reg.c
@@ -1,4 +1,4 @@
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
@@ -6,7 +6,6 @@
* 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
@@ -29,89 +28,6 @@
#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 )
-{
- UNISTR2 unistr;
- uint32 real_size = 0;
- char *string;
- char *list = NULL;
- char *list2 = NULL;
-
- if ( !buf2 || !val )
- return 0;
-
- real_size = val->size;
-
- switch (val->type )
- {
- case REG_SZ:
- string = (char*)val->data_p;
- DEBUG(10,("reg_init_buffer2: REG_SZ string => [%s]\n", string));
-
- init_unistr2( &unistr, (char*)val->data_p, strlen((char*)val->data_p)+1 );
- init_buffer2( buf2, (char*)unistr.buffer, unistr.uni_str_len*2 );
- real_size = unistr.uni_str_len*2;
- break;
-
- case REG_MULTI_SZ:
- string = (char*)val->data_p;
- real_size = 0;
- while ( string && *string )
- {
- DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ string => [%s], size => [%d]\n", string, real_size ));
-
- init_unistr2( &unistr, string, strlen(string)+1 );
-
- list2 = Realloc( list, real_size + unistr.uni_str_len*2 );
- if ( !list2 )
- break;
- list = list2;
-
- memcpy( list+real_size, unistr.buffer, unistr.uni_str_len*2 );
-
- real_size += unistr.uni_str_len*2;
-
- string += strlen(string)+1;
- }
-
- list2 = Realloc( list, real_size + 2 );
- if ( !list2 )
- break;
- list = list2;
- list[real_size++] = 0x0;
- list[real_size++] = 0x0;
-
- init_buffer2( buf2, (char*)list, real_size );
-
- DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ size => [%d]\n", real_size ));
-
- break;
-
- case REG_BINARY:
- DEBUG(10,("reg_init_buffer2: REG_BINARY size => [%d]\n", val->size ));
-
- init_buffer2( buf2, val->data_p, val->size );
- break;
-
- case REG_DWORD:
- DEBUG(10,("reg_init_buffer2: REG_DWORD value => [%d]\n", *(uint32*)val->data_p));
- init_buffer2( buf2, val->data_p, val->size );
- break;
-
- default:
- DEBUG(0,("reg_init_buffer2: Unsupported registry data type [%d]\n", val->type));
- break;
- }
-
- SAFE_FREE( list );
-
- return real_size;
-}
-
-/*******************************************************************
Inits a structure.
********************************************************************/
@@ -249,8 +165,6 @@ BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
}
-
-
/*******************************************************************
Inits a structure.
********************************************************************/
@@ -669,7 +583,7 @@ BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int d
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;
@@ -685,7 +599,6 @@ void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd)
memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
}
-
/*******************************************************************
reads or writes a structure.
********************************************************************/
@@ -700,7 +613,7 @@ BOOL reg_io_q_unknown_1a(char *desc, REG_Q_UNKNOWN_1A *r_q, prs_struct *ps, int
if(!prs_align(ps))
return False;
-
+
if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
return False;
@@ -721,7 +634,7 @@ BOOL reg_io_r_unknown_1a(char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int
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))
@@ -730,57 +643,6 @@ BOOL reg_io_r_unknown_1a(char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int
return True;
}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-
-BOOL reg_io_q_save_key(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(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.
********************************************************************/
@@ -1163,77 +1025,33 @@ BOOL reg_io_q_info(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;
+ if(r_r == NULL)
+ return False;
+
- r_r->ptr_type = 1;
- r_r->type = type;
+ r_r->ptr_type = 1;
+ r_r->type = 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 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_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;
+
}
/*******************************************************************
@@ -1263,7 +1081,7 @@ BOOL reg_io_r_info(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;
}
@@ -1321,46 +1139,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_uni_hdr( &r_u->hdr_name, strlen(val->valuename)+1 );
- init_unistr2( &r_u->uni_name, val->valuename, strlen(val->valuename)+1 );
-
- /* 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.
********************************************************************/
@@ -1380,7 +1158,6 @@ BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int d
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))
@@ -1451,7 +1228,7 @@ BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
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;
@@ -1754,7 +1531,7 @@ BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int
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("asccess_desired ", ps, depth, &r_q->access_desired))
return False;
return True;
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index 1137993bb6..c16232204c 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -5,10 +5,8 @@
* 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) Anthony Liguori 2002,
- * Copyright (C) Jim McDonough 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
@@ -5069,7 +5067,7 @@ BOOL samr_io_r_create_user(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;
@@ -5947,7 +5945,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
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);
@@ -6719,84 +6717,6 @@ BOOL samr_io_r_connect(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)
-{
- int len_srv_name = strlen(srv_name);
-
- DEBUG(5, ("init_samr_q_connect\n"));
-
- /* make PDC server name \\server */
- q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0;
- init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name + 1);
-
- /* 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(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(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.
********************************************************************/
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index ac41a81a5a..b10a5c4377 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -322,7 +322,7 @@ reads or writes an NOTIFY INFO DATA structure.
static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
{
- uint32 useless_ptr=0x0FF0ADDE;
+ uint32 useless_ptr=0xADDE0FF0;
prs_debug(ps, depth, desc, "smb_io_notify_info_data");
depth++;
@@ -378,14 +378,6 @@ static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs
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));
@@ -459,13 +451,6 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
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;
-
default:
DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
data->enc_type));
@@ -690,11 +675,9 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
Let the size determine that */
switch (devmode->specversion) {
- /* list of observed spec version's */
case 0x0320:
case 0x0400:
case 0x0401:
- case 0x040d:
break;
default:
@@ -5200,7 +5183,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, 0, 0);
+ rpcstr_pull(f, src, sizeof(f)-1, -1, 0);
src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
tar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
if (!tar)
@@ -6188,6 +6171,42 @@ BOOL spoolss_io_r_resetprinter(char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct
/*******************************************************************
********************************************************************/
+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_ascii((*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(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
{
@@ -6731,7 +6750,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;
@@ -7509,31 +7528,3 @@ BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u,
return True;
}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
- uint32 flags, uint32 options, 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,
- strlen(localmachine) + 1);
-
- q_u->printerlocal = printerlocal;
-
- if (option)
- q_u->option_ptr = 1;
-
- q_u->option = option;
-
- return True;
-}
diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c
index 531267c308..3dc054d2b1 100644
--- a/source3/rpc_parse/parse_srv.c
+++ b/source3/rpc_parse/parse_srv.c
@@ -3,10 +3,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.
+ * 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
@@ -29,71 +28,6 @@
#define DBGC_CLASS DBGC_RPC_PARSE
/*******************************************************************
- Inits a SH_INFO_0_STR structure
-********************************************************************/
-
-void init_srv_share_info0_str(SH_INFO_0_STR *sh0, char *net_name)
-{
- DEBUG(5,("init_srv_share_info0_str\n"));
-
- if(net_name)
- init_unistr2(&sh0->uni_netname, net_name, strlen(net_name)+1);
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info0_str(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, 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(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
********************************************************************/
@@ -101,10 +35,8 @@ void init_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark)
{
DEBUG(5,("init_srv_share_info1_str\n"));
- if(net_name)
- init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1);
- if(remark)
- init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1);
+ init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1);
+ init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1);
}
/*******************************************************************
@@ -115,24 +47,20 @@ static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *p
{
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;
}
@@ -143,7 +71,7 @@ static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *p
void init_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, 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;
@@ -211,7 +139,6 @@ static BOOL srv_io_share_info2_str(char *desc, SH_INFO_2 *sh, SH_INFO_2_STR *sh2
if(!prs_align(ps))
return False;
-
if (sh->ptr_netname)
if(!smb_io_unistr2("", &sh2->uni_netname, True, ps, depth))
return False;
@@ -248,6 +175,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;
}
@@ -288,21 +216,6 @@ static BOOL srv_io_share_info2(char *desc, SH_INFO_2 *sh2, prs_struct *ps, int d
}
/*******************************************************************
- Inits a SH_INFO_501_STR structure
-********************************************************************/
-
-void init_srv_share_info501_str(SH_INFO_501_STR *sh501,
- char *net_name, char *remark)
-{
- DEBUG(5,("init_srv_share_info501_str\n"));
-
- if(net_name)
- init_unistr2(&sh501->uni_netname, net_name, strlen(net_name)+1);
- if(remark)
- init_unistr2(&sh501->uni_remark, remark, strlen(remark)+1);
-}
-
-/*******************************************************************
Inits a SH_INFO_2 structure
*******************************************************************/
@@ -346,6 +259,18 @@ static BOOL srv_io_share_info501(char *desc, SH_INFO_501 *sh501, prs_struct *ps,
return True;
}
+/********************************************************************
+ Inits a SH_INFO_501_STR structure
+********************************************************************/
+
+void init_srv_share_info501_str(SH_INFO_501_STR *sh501, char *net_name, 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.
********************************************************************/
@@ -376,7 +301,7 @@ static BOOL srv_io_share_info501_str(char *desc, SH_INFO_501_STR *sh501, prs_str
********************************************************************/
void init_srv_share_info502(SH_INFO_502 *sh502,
- const char *net_name, uint32 type, char *remark,
+ char *net_name, uint32 type, char *remark,
uint32 perms, uint32 max_uses, uint32 num_uses,
char *path, char *passwd, SEC_DESC *psd, size_t sd_size)
{
@@ -390,9 +315,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;
}
@@ -428,7 +353,7 @@ static BOOL srv_io_share_info502(char *desc, SH_INFO_502 *sh502, prs_struct *ps,
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;
@@ -441,22 +366,26 @@ static BOOL srv_io_share_info502(char *desc, SH_INFO_502 *sh502, prs_struct *ps,
********************************************************************/
void init_srv_share_info502_str(SH_INFO_502_STR *sh502str,
+ SH_INFO_502 *ptrs,
char *net_name, char *remark,
char *path, char *passwd, SEC_DESC *psd, size_t sd_size)
{
DEBUG(5,("init_srv_share_info502_str\n"));
- if(net_name)
+ sh502str->ptrs = ptrs;
+
+ if(sh502str->ptrs->ptr_netname)
init_unistr2(&sh502str->uni_netname, net_name, strlen(net_name)+1);
- if(remark)
+ if(sh502str->ptrs->ptr_remark)
init_unistr2(&sh502str->uni_remark, remark, strlen(remark)+1);
- if(path)
+ if(sh502str->ptrs->ptr_path)
init_unistr2(&sh502str->uni_path, path, strlen(path)+1);
- if(passwd)
+ if(sh502str->ptrs->ptr_passwd)
init_unistr2(&sh502str->uni_passwd, passwd, strlen(passwd)+1);
+ if(sh502str->ptrs->ptr_sd) {
sh502str->sd = psd;
- sh502str->reserved = 0;
sh502str->sd_size = sd_size;
+ }
}
/*******************************************************************
@@ -507,112 +436,21 @@ static BOOL srv_io_share_info502_str(char *desc, SH_INFO_502_STR *sh502, prs_str
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, char *remark)
-{
- DEBUG(5,("init_srv_share_info1004_str\n"));
-
- if(remark)
- init_unistr2(&sh1004->uni_remark, remark, strlen(remark)+1);
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info1004_str(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, 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(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(char* desc, SRV_SHARE_INFO_1005* sh1005, prs_struct* ps, int depth)
+static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005,
+ prs_struct* ps, int depth)
{
if(sh1005 == NULL)
return False;
@@ -633,95 +471,6 @@ static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005, prs_s
Reads or writes a structure.
********************************************************************/
-static BOOL srv_io_share_info1006(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"));
-
- if(alternate_directory_name)
- init_unistr2(&sh1007->uni_AlternateDirectoryName, alternate_directory_name, strlen(alternate_directory_name)+1);
-}
-
-/*******************************************************************
- Reads or writes a structure.
-********************************************************************/
-
-static BOOL srv_io_share_info1007_str(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(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(char* desc, SRV_SHARE_INFO_1501* sh1501,
prs_struct* ps, int depth)
{
@@ -762,6 +511,9 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
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))
@@ -789,33 +541,6 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
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;
@@ -834,7 +559,6 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
}
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;
}
@@ -908,123 +632,11 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
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;
}
@@ -1055,9 +667,8 @@ void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
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.num_entries = 0;
+ q_n->ctr.ptr_entries = 0;
q_n->preferred_len = preferred_len;
memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
@@ -1118,12 +729,8 @@ BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *
if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
return False;
-
- if(r_n->total_entries != 0) {
- if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
- 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))
return False;
@@ -1131,25 +738,6 @@ BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *
}
/*******************************************************************
- 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.
********************************************************************/
@@ -1204,24 +792,10 @@ static BOOL srv_io_srv_share_info(char *desc, prs_struct *ps, int depth, SRV_SHA
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;
@@ -1245,40 +819,16 @@ static BOOL srv_io_srv_share_info(char *desc, prs_struct *ps, int depth, SRV_SHA
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;
@@ -1320,34 +870,6 @@ BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_
}
/*******************************************************************
- 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.
********************************************************************/
@@ -1382,15 +904,6 @@ BOOL srv_io_q_net_share_set_info(char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n, prs_
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;
}
@@ -1398,9 +911,9 @@ BOOL srv_io_q_net_share_set_info(char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n, prs_
Reads or writes a structure.
********************************************************************/
-BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *r_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_share_set_info(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");
@@ -1409,22 +922,14 @@ BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *r_n, prs_
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.
********************************************************************/
@@ -1457,9 +962,6 @@ BOOL srv_io_q_net_share_add(char *desc, SRV_Q_NET_SHARE_ADD *q_n, prs_struct *ps
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)
@@ -1492,9 +994,9 @@ void init_srv_q_net_share_add(SRV_Q_NET_SHARE_ADD *q, char *srvname,
Reads or writes a structure.
********************************************************************/
-BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *r_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_share_add(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");
@@ -1503,25 +1005,14 @@ BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *r_n, prs_struct *ps
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)
{
@@ -2398,8 +1889,8 @@ static BOOL srv_io_file_info3_str(char *desc, FILE_INFO_3_STR *sh1, prs_struct *
********************************************************************/
void init_srv_file_info3(FILE_INFO_3 *fl3,
- uint32 id, uint32 perms, uint32 num_locks,
- char *path_name, char *user_name)
+ uint32 id, uint32 perms, uint32 num_locks,
+ char *path_name, char *user_name)
{
DEBUG(5,("init_srv_file_info3: %s %s\n", path_name, user_name));
@@ -2513,8 +2004,7 @@ static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *
********************************************************************/
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,
+ char *srv_name, char *qual_name, char *user_name,
uint32 file_level, SRV_FILE_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
@@ -2805,7 +2295,7 @@ void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, 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);
}
@@ -3069,7 +2559,7 @@ BOOL srv_io_r_net_srv_set_info(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))
@@ -3198,31 +2688,6 @@ BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *
}
/*******************************************************************
- 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.
********************************************************************/
@@ -3272,9 +2737,7 @@ BOOL srv_io_q_net_disk_enum(char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_struct *ps
BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth)
{
-
int i;
- uint32 entries_read, entries_read2, entries_read3;
if (r_n == NULL)
return False;
@@ -3282,36 +2745,23 @@ BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps
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))
+ if(!prs_uint32("actual_elements", ps, depth, &r_n->disk_enum_ctr.entries_read))
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)))
- return False;
- r_n->disk_enum_ctr.disk_info = dinfo;
- }
-
for(i=0; i < r_n->disk_enum_ctr.entries_read; i++) {
if(!prs_uint32("unknown", ps, depth, &r_n->disk_enum_ctr.disk_info[i].unknown))
@@ -3337,25 +2787,6 @@ BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps
}
/*******************************************************************
- 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.
********************************************************************/
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c
index e3495576c9..e5a4d3b46d 100644
--- a/source3/rpc_server/srv_lsa.c
+++ b/source3/rpc_server/srv_lsa.c
@@ -3,9 +3,8 @@
* 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 2002.
+ * 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
@@ -611,37 +610,6 @@ static BOOL api_lsa_query_secobj(pipes_struct *p)
}
/***************************************************************************
- 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
***************************************************************************/
@@ -666,7 +634,6 @@ static struct api_struct api_lsa_cmds[] =
{ "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs },
{ "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs },
{ "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj },
- { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 },
{ NULL , 0 , NULL }
};
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index f28441886a..d072061a5f 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -5,8 +5,7 @@
* 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 2002.
+ * 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
@@ -343,48 +342,6 @@ static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *s
}
/***************************************************************************
- init_dns_dom_info.
- ***************************************************************************/
-static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, char *nb_name,
- char *dns_name, char *forest_name,
- GUID *dom_guid, DOM_SID *dom_sid)
-{
- if (nb_name && *nb_name) {
- init_uni_hdr(&r_l->hdr_nb_dom_name, strlen(nb_name));
- init_unistr2(&r_l->uni_nb_dom_name, nb_name,
- strlen(nb_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_uni_hdr(&r_l->hdr_dns_dom_name, strlen(dns_name));
- init_unistr2(&r_l->uni_dns_dom_name, dns_name,
- strlen(dns_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_uni_hdr(&r_l->hdr_forest_name, strlen(forest_name));
- init_unistr2(&r_l->uni_forest_name, forest_name,
- strlen(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(GUID));
- }
-
- if (dom_sid) {
- r_l->ptr_dom_sid = 1;
- init_dom_sid2(&r_l->dom_sid, dom_sid);
- }
-}
-
-/***************************************************************************
_lsa_open_policy2.
***************************************************************************/
@@ -1209,55 +1166,3 @@ NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUER
}
-NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
-{
- struct lsa_info *handle;
- char *nb_name = NULL;
- char *dns_name = NULL;
- char *forest_name = NULL;
- DOM_SID *sid = NULL;
- GUID guid;
-
- ZERO_STRUCT(guid);
- r_u->status = NT_STATUS_OK;
-
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
- 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 = global_myworkgroup;
- /* ugly temp hack for these next two */
- dns_name = lp_realm();
- forest_name = lp_realm();
- sid = get_global_sam_sid();
- secrets_fetch_domain_guid(global_myworkgroup,
- &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;
- }
-
- return r_u->status;
-}
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 8f6011826a..4ab9c470d0 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -280,7 +280,7 @@ NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
/* 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);
+ (char *)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)) {
@@ -342,7 +342,7 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
/* 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);
+ (char *)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)) {
@@ -708,7 +708,7 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
pdb_get_username(sampw),
pdb_get_fullname(sampw),
pdb_get_homedir(sampw),
- pdb_get_dir_drive(sampw),
+ pdb_get_dirdrive(sampw),
pdb_get_logon_script(sampw),
pdb_get_profile_path(sampw),
pdb_get_logon_time(sampw),
diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c
index d0aaf0199b..a096325860 100644
--- a/source3/rpc_server/srv_reg.c
+++ b/source3/rpc_server/srv_reg.c
@@ -83,7 +83,7 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
}
/*******************************************************************
- api_reg_open_khu
+ api_reg_open_khlm
********************************************************************/
static BOOL api_reg_open_hku(pipes_struct *p)
@@ -108,32 +108,6 @@ static BOOL api_reg_open_hku(pipes_struct *p)
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
@@ -316,56 +290,6 @@ static BOOL api_reg_enum_key(pipes_struct *p)
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;
-}
-
/*******************************************************************
@@ -375,17 +299,14 @@ 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 },
{ NULL , 0 , NULL }
};
diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c
index cd9596d2a7..3f07e4aaea 100644
--- a/source3/rpc_server/srv_reg_nt.c
+++ b/source3/rpc_server/srv_reg_nt.c
@@ -1,11 +1,12 @@
/*
* 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.
+ * 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.
+ * 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
@@ -29,134 +30,386 @@
#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 KEY_HKLM "HKLM"
+#define KEY_HKU "HKU"
#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())
+/* structure to store the registry handles */
-static REGISTRY_KEY *regkeys_list;
+typedef struct _RegistryKey {
+ struct _RegistryKey *prev, *next;
+ fstring name; /* name of registry key */
+ POLICY_HND hnd;
+
+} Registry_Key;
-/******************************************************************
- free() function for REGISTRY_KEY
- *****************************************************************/
+static Registry_Key *regkeys_list;
+static TDB_CONTEXT *tdb_reg;
+
+/***********************************************************************
+ 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
+ ***********************************************************************/
-static void free_regkey_info(void *ptr)
+static BOOL store_reg_keys( TDB_CONTEXT *tdb, char *keyname, char **subkeys, uint32 num_subkeys )
{
- REGISTRY_KEY *info = (REGISTRY_KEY*)ptr;
+ TDB_DATA kbuf, dbuf;
+ char *buffer, *tmpbuf;
+ int i = 0;
+ uint32 len, buflen;
+ BOOL ret = True;
- DLIST_REMOVE(regkeys_list, info);
+ if ( !keyname )
+ return False;
+
+ /* 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", subkeys[i]);
+ if ( len > buflen ) {
+ /* allocate some extra space */
+ if ((tmpbuf = Realloc( buffer, len*2 )) == NULL) {
+ DEBUG(0,("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", subkeys[i]);
+ }
+ }
+
+ /* finally write out the data */
+
+ kbuf.dptr = keyname;
+ kbuf.dsize = strlen(keyname)+1;
+ dbuf.dptr = buffer;
+ dbuf.dsize = len;
+ if ( tdb_store( tdb, kbuf, dbuf, TDB_REPLACE ) == -1) {
+ ret = False;
+ goto done;
+ }
- SAFE_FREE(info);
+done:
+ SAFE_FREE( buffer );
+ return ret;
}
-/******************************************************************
- Find a registry key handle and return a REGISTRY_KEY
- *****************************************************************/
+/***********************************************************************
+ 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
+ ***********************************************************************/
-static REGISTRY_KEY *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
+static int fetch_reg_keys( TDB_CONTEXT *tdb, char* key, char **subkeys )
{
- REGISTRY_KEY *regkey = NULL;
+ pstring path;
+ uint32 num_items;
+ TDB_DATA dbuf;
+ char *buf;
+ uint32 buflen, len;
+ int i;
+ char *s;
- if(!find_policy_by_hnd(p,hnd,(void **)&regkey)) {
- DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
- return NULL;
+
+ pstrcpy( path, key );
+
+ /* convert to key format */
+ pstring_sub( path, "\\", "/" );
+
+ dbuf = tdb_fetch_by_string( tdb, path );
+
+ buf = dbuf.dptr;
+ buflen = dbuf.dsize;
+
+ if ( !buf ) {
+ DEBUG(5,("fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key));
+ return 0;
+ }
+
+ len = tdb_unpack( buf, buflen, "d", &num_items);
+ if (num_items) {
+ if ( (*subkeys = (char*)malloc(sizeof(fstring)*num_items)) == NULL ) {
+ DEBUG(0,("fetch_reg_keys: Failed to malloc memory for subkey array containing [%d] items!\n",
+ num_items));
+ num_items = -1;
+ goto done;
+ }
+ }
+
+ s = *subkeys;
+ for (i=0; i<num_items; i++) {
+ len += tdb_unpack( buf+len, buflen-len, "f", s );
+ s += strlen(s) + 1;
}
- return regkey;
+done:
+ SAFE_FREE(dbuf.dptr);
+ return num_items;
}
+/***********************************************************************
+ count the number of subkeys dtored in the registry
+ ***********************************************************************/
-/*******************************************************************
- 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,
- char *subkeyname, uint32 access_granted )
+static int fetch_reg_keys_count( TDB_CONTEXT *tdb, char* key )
{
- REGISTRY_KEY *regkey = NULL;
- NTSTATUS result = NT_STATUS_OK;
- REGSUBKEY_CTR subkeys;
+ pstring path;
+ uint32 num_items;
+ TDB_DATA dbuf;
+ char *buf;
+ uint32 buflen, len;
- DEBUG(7,("open_registry_key: name = [%s][%s]\n",
- parent ? parent->name : "NULL", subkeyname));
-
- 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
- */
+ pstrcpy( path, key );
+
+ /* convert to key format */
+ pstring_sub( path, "\\", "/" );
- if (!subkeyname || !*subkeyname ) {
- pstrcpy( regkey->name, parent->name );
+ dbuf = tdb_fetch_by_string( tdb, path );
+
+ buf = dbuf.dptr;
+ buflen = dbuf.dsize;
+
+ if ( !buf ) {
+ DEBUG(5,("fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key));
+ return 0;
}
- else {
- pstrcpy( regkey->name, "" );
- if ( parent ) {
- pstrcat( regkey->name, parent->name );
- pstrcat( regkey->name, "\\" );
+
+ len = tdb_unpack( buf, buflen, "d", &num_items);
+
+ SAFE_FREE( buf );
+
+ return num_items;
+}
+
+/***********************************************************************
+ retreive a specific subkey specified by index. The subkey parameter
+ is assumed to be an fstring.
+ ***********************************************************************/
+
+static BOOL fetch_reg_keys_specific( TDB_CONTEXT *tdb, char* key, char* subkey,
+ uint32 key_index )
+{
+ int num_subkeys, i;
+ char *subkeys = NULL;
+ char *s;
+
+ num_subkeys = fetch_reg_keys( tdb_reg, key, &subkeys );
+ if ( num_subkeys == -1 )
+ return False;
+
+ s = subkeys;
+ for ( i=0; i<num_subkeys; i++ ) {
+ /* copy the key if the index matches */
+ if ( i == key_index ) {
+ fstrcpy( subkey, s );
+ break;
}
- pstrcat( regkey->name, subkeyname );
+
+ /* go onto the next string */
+ s += strlen(s) + 1;
}
- /* Look up the table of registry I/O operations */
+ SAFE_FREE(subkeys);
+
+ return True;
+}
- 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;
- }
+
+/***********************************************************************
+ Open the registry database
+ ***********************************************************************/
+
+static BOOL init_registry_data( TDB_CONTEXT* registry_tdb )
+{
+ pstring keyname;
+ char *subkeys[3];
+
+ /* HKEY_LOCAL_MACHINE */
- /* check if the path really exists; failed is indicated by -1 */
- /* if the subkey count failed, bail out */
+ pstrcpy( keyname, KEY_HKLM );
+ subkeys[0] = "SYSTEM";
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 1 ))
+ return False;
+
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SYSTEM" );
+ subkeys[0] = "CurrentControlSet";
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 1 ))
+ return False;
+
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SYSTEM/CurrentControlSet" );
+ subkeys[0] = "Control";
+ subkeys[1] = "services";
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 2 ))
+ return False;
+
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" );
+ subkeys[0] = "Print";
+ subkeys[1] = "ProduceOptions";
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 2 ))
+ return False;
+
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/Print" );
+ subkeys[0] = "Environments";
+ subkeys[1] = "Forms";
+ subkeys[2] = "Printers";
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 3 ))
+ return False;
+
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/ProductOptions" );
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 0 ))
+ return False;
+
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SYSTEM/CurrentControlSet/services" );
+ subkeys[0] = "Netlogon";
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 1 ))
+ return False;
+
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon" );
+ subkeys[0] = "parameters";
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 1 ))
+ return False;
+
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon/parameters" );
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 0 ))
+ return False;
- ZERO_STRUCTP( &subkeys );
- regsubkey_ctr_init( &subkeys );
+ /* HKEY_USER */
+
+ pstrcpy( keyname, KEY_HKU );
+ if ( !store_reg_keys( registry_tdb, keyname, subkeys, 0 ) )
+ return False;
+
+ return True;
+}
+
+/***********************************************************************
+ Open the registry database
+ ***********************************************************************/
+
+BOOL init_registry( void )
+{
+ static pid_t local_pid;
- if ( fetch_reg_keys( regkey, &subkeys ) == -1 ) {
- /* don't really know what to return here */
+ 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;
+ }
- 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
- */
+ DEBUG(10,("init_registry: Successfully created registry tdb\n"));
- if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) )
- result = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ /* create the registry here */
+ if ( !init_registry_data( tdb_reg ) ) {
+ DEBUG(0,("init_registry: Failed to initiailize data in registry!\n"));
+ return False;
+ }
}
+
+ local_pid = sys_getpid();
- /* clean up */
+ return True;
+}
+
+/******************************************************************
+ Find a registry key handle and return a Registry_Key
+ *****************************************************************/
+
+static Registry_Key *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
+{
+ 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;
+}
+
+
+/******************************************************************
+ free() function for Registry_Key
+ *****************************************************************/
+
+static void free_reg_info(void *ptr)
+{
+ Registry_Key *info = (Registry_Key*)ptr;
+
+ DLIST_REMOVE(regkeys_list, info);
+
+ 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 open_registry_key(pipes_struct *p, POLICY_HND *hnd, char *name,
+ uint32 access_granted)
+{
+ Registry_Key *regkey = NULL;
- regsubkey_ctr_destroy( &subkeys );
+ DEBUG(7,("open_registry_key: name = [%s]\n", name));
+
+ /* All registry keys **must** have a name of non-zero length */
+
+ if (!name || !*name )
+ return False;
+
+ if ((regkey=(Registry_Key*)malloc(sizeof(Registry_Key))) == NULL)
+ return False;
+
+ ZERO_STRUCTP( regkey );
- if ( ! NT_STATUS_IS_OK(result) )
- SAFE_FREE( regkey );
- else
- DLIST_ADD( regkeys_list, regkey );
+ DLIST_ADD( regkeys_list, regkey );
+ /* copy the name and obtain a handle */
+
+ fstrcpy( regkey->name, name );
DEBUG(7,("open_registry_key: exit\n"));
-
- return result;
+
+ return create_policy_hnd( p, hnd, free_reg_info, regkey );
}
/*******************************************************************
@@ -166,7 +419,7 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd)
{
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd(p, 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)));
@@ -182,37 +435,35 @@ static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd)
retrieve information about the subkeys
*******************************************************************/
-static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *maxlen )
+static BOOL get_subkey_information( Registry_Key *key, uint32 *maxnum, uint32 *maxlen )
{
- int num_subkeys, i;
- uint32 max_len;
- REGSUBKEY_CTR subkeys;
- uint32 len;
+ int num_subkeys, i;
+ uint32 max_len;
+ char *subkeys = NULL;
+ uint32 len;
+ char *s;
if ( !key )
return False;
-
- ZERO_STRUCTP( &subkeys );
- regsubkey_ctr_init( &subkeys );
-
- if ( fetch_reg_keys( key, &subkeys ) == -1 )
+ num_subkeys = fetch_reg_keys( tdb_reg, key->name, &subkeys );
+ if ( num_subkeys == -1 )
return False;
/* find the longest string */
max_len = 0;
- num_subkeys = regsubkey_ctr_numkeys( &subkeys );
-
+ s = subkeys;
for ( i=0; i<num_subkeys; i++ ) {
- len = strlen( regsubkey_ctr_specific_key(&subkeys, i) );
+ len = strlen(s);
max_len = MAX(max_len, len);
+ s += len + 1;
}
*maxnum = num_subkeys;
*maxlen = max_len*2;
- regsubkey_ctr_destroy( &subkeys );
+ SAFE_FREE(subkeys);
return True;
}
@@ -223,47 +474,29 @@ static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *m
Samba tdb's (such as ntdrivers.tdb).
*******************************************************************/
-static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
+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 );
+ /* Hard coded key names first */
+ /* nothing has valuies right now */
- val = regval_ctr_specific_value( &values, i );
- }
-
- *maxnum = num_values;
- *maxlen = lenmax;
- *maxsize = sizemax;
-
- regval_ctr_destroy( &values );
-
+ *maxnum = 0;
+ *maxlen = 0;
+ *maxsize = 0;
return True;
-}
+#if 0 /* JERRY */
+ /*
+ * FIXME!!! Need to add routines to look up values in other
+ * databases --jerry
+ */
+
+ return False;
+#endif
+}
/********************************************************************
reg_close
@@ -282,27 +515,27 @@ NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
}
/*******************************************************************
+ 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 );
-}
-
-/*******************************************************************
- ********************************************************************/
+ if (!open_registry_key(p, &r_u->pol, KEY_HKLM, 0x0))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-NTSTATUS _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
-{
- return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, 0x0 );
+ return NT_STATUS_OK;
}
/*******************************************************************
+ reg_reply_open
********************************************************************/
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 );
+ if (!open_registry_key(p, &r_u->pol, KEY_HKU, 0x0))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -313,8 +546,9 @@ 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;
+ pstring path;
+ int num_subkeys;
+ Registry_Key *key = find_regkey_index_by_hnd(p, &q_u->pol);
DEBUG(5,("reg_open_entry: Enter\n"));
@@ -322,14 +556,26 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR
return NT_STATUS_INVALID_HANDLE;
rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0);
+
+ /* store the full path in the regkey_list */
- DEBUG(5,("reg_open_entry: Enter\n"));
-
- result = open_registry_key( p, &pol, key, name, 0x0 );
+ pstrcpy( path, key->name );
+ pstrcat( path, "\\" );
+ pstrcat( path, name );
+
+ DEBUG(5,("reg_open_entry: %s\n", path));
+
+ /* do a check on the name, here */
- init_reg_r_open_entry( r_u, &pol, result );
+ if ( (num_subkeys=fetch_reg_keys_count( tdb_reg, path )) == -1 )
+ return NT_STATUS_ACCESS_DENIED;
- DEBUG(5,("reg_open_entry: Exit\n"));
+ if (!open_registry_key(p, &pol, path, 0x0))
+ return NT_STATUS_TOO_MANY_SECRETS;
+
+ init_reg_r_open_entry(r_u, &pol, NT_STATUS_OK);
+
+ DEBUG(5,("reg_open_entry: Exitn"));
return r_u->status;
}
@@ -340,85 +586,66 @@ 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;
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
- REGISTRY_VALUE *val = NULL;
- REGISTRY_VALUE emptyval;
- REGVAL_CTR regvals;
- int i;
+ NTSTATUS status = NT_STATUS_OK;
+ char *value = NULL;
+ uint32 type = 0x1; /* key type: REG_SZ */
+ UNISTR2 *uni_key = NULL;
+ BUFFER2 *buf = NULL;
+ fstring name;
+ Registry_Key *key = find_regkey_index_by_hnd( p, &q_u->pol );
DEBUG(5,("_reg_info: Enter\n"));
- if ( !regkey )
+ if ( !key )
return NT_STATUS_INVALID_HANDLE;
- DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
-
+ DEBUG(7,("_reg_info: policy key name = [%s]\n", key->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));
+ DEBUG(5,("reg_info: checking subkey: %s\n", name));
- ZERO_STRUCTP( &regvals );
-
- regval_ctr_init( &regvals );
+ uni_key = (UNISTR2 *)talloc_zero(p->mem_ctx, sizeof(UNISTR2));
+ buf = (BUFFER2 *)talloc_zero(p->mem_ctx, sizeof(BUFFER2));
- /* couple of hard coded registry values */
-
- if ( strequal(name, "RefusePasswordChange") ) {
- ZERO_STRUCTP( &emptyval );
- val = &emptyval;
-
- goto out;
- }
+ if (!uni_key || !buf)
+ return NT_STATUS_NO_MEMORY;
- 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:
- regval_ctr_addvalue( &regvals, REGSTR_PRODUCTTYPE, REG_SZ, REG_PT_LANMANNT, strlen(REG_PT_LANMANNT)+1 );
- break;
- case ROLE_STANDALONE:
- regval_ctr_addvalue( &regvals, REGSTR_PRODUCTTYPE, REG_SZ, REG_PT_SERVERNT, strlen(REG_PT_SERVERNT)+1 );
- break;
- case ROLE_DOMAIN_MEMBER:
- regval_ctr_addvalue( &regvals, REGSTR_PRODUCTTYPE, REG_SZ, REG_PT_WINNT, strlen(REG_PT_WINNT)+1 );
- break;
- }
-
- val = dup_registry_value( regval_ctr_specific_value( &regvals, 0 ) );
-
- status = NT_STATUS_OK;
+ 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);
+ buf->buf_max_len=4;
+
goto out;
}
- /* 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;
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ value = "LanmanNT";
+ break;
+ case ROLE_STANDALONE:
+ value = "ServerNT";
+ break;
+ case ROLE_DOMAIN_MEMBER:
+ value = "WinNT";
break;
- }
-
- free_registry_value( val );
}
+ /* 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. */
+
+ init_unistr2(uni_key, value, strlen(value)+1);
+ init_buffer2(buf, (uint8*)uni_key->buffer, uni_key->uni_str_len*2);
-out:
- new_init_reg_r_info(q_u->ptr_buf, r_u, val, status);
-
- regval_ctr_destroy( &regvals );
- free_registry_value( val );
+ out:
+ init_reg_r_info(q_u->ptr_buf, r_u, buf, type, status);
- DEBUG(5,("_reg_info: Exit\n"));
+ DEBUG(5,("reg_open_entry: Exit\n"));
return status;
}
@@ -431,7 +658,7 @@ out:
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 );
+ Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
DEBUG(5,("_reg_query_key: Enter\n"));
@@ -443,7 +670,6 @@ NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *
if ( !get_value_information( regkey, &r_u->num_values, &r_u->max_valnamelen, &r_u->max_valbufsize ) )
return NT_STATUS_ACCESS_DENIED;
-
r_u->sec_desc = 0x00000078; /* size for key's sec_desc */
@@ -465,7 +691,7 @@ NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *
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 );
+ Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
DEBUG(5,("_reg_unknown_1a: Enter\n"));
@@ -487,8 +713,8 @@ NTSTATUS _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1
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;
+ Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
+ fstring subkey;
DEBUG(5,("_reg_enum_key: Enter\n"));
@@ -498,9 +724,9 @@ NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u
DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", regkey->name));
- if ( !fetch_reg_keys_specific( regkey, &subkey, q_u->key_index ) )
+ if ( !fetch_reg_keys_specific( tdb_reg, regkey->name, subkey, q_u->key_index ) )
{
- status = NT_STATUS_NO_MORE_ENTRIES;
+ status = werror_to_ntstatus( WERR_NO_MORE_ITEMS );
goto done;
}
@@ -513,46 +739,6 @@ NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u
DEBUG(5,("_reg_enum_key: Exit\n"));
done:
- SAFE_FREE( subkey );
- return status;
-}
-
-/*****************************************************************************
- 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;
- }
-
- 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;
}
@@ -622,28 +808,4 @@ NTSTATUS _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_A
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/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index bc3b8970d6..f002a7d1c9 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -3,11 +3,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) Anthony Liguori 2002,
- * Copyright (C) Jim McDonough 2002.
+ * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Marc Jacobsen 1999.
+ * Copyright (C) Jean François Micouleau 1998-2001.
*
* Split into interface and implementation modules by,
*
@@ -654,37 +652,6 @@ static BOOL api_samr_connect(pipes_struct *p)
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"));
- return False;
- }
-
- return True;
-}
-
/**********************************************************************
api_samr_lookup_domain
**********************************************************************/
@@ -1498,7 +1465,6 @@ static struct api_struct api_samr_cmds [] =
{"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 },
{NULL , 0 , NULL }
};
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index a30622c600..88d728d810 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -3,12 +3,10 @@
* 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) Anthony Liguori 2002,
- * Copyright (C) Jim McDonough 2002.
+ * 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
@@ -729,6 +727,8 @@ static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UN
}
for (i = 0; i < num_entries; i++) {
+ int len = uni_temp_name.uni_str_len;
+
pwd = disp_user_info[i+start_idx].sam;
temp_name = pdb_get_username(pwd);
init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
@@ -743,7 +743,7 @@ static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UN
return NT_STATUS_UNSUCCESSFUL;
}
- init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
+ init_sam_entry(&sam[i], len, user_rid);
copy_unistr2(&uni_name[i], &uni_temp_name);
}
@@ -1081,9 +1081,7 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM
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(p->mem_ctx, &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);
@@ -2083,8 +2081,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)
@@ -2102,22 +2098,12 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
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_MIN_PASSWORD_LEN, &min_pass_len);
+ account_policy_get(AP_PASSWORD_HISTORY, &pass_hist);
+ account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &flag);
+ account_policy_get(AP_MAX_PASSWORD_AGE, (int *)&u_expire);
+ account_policy_get(AP_MIN_PASSWORD_AGE, (int *)&u_min_age);
- 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);
@@ -2163,15 +2149,10 @@ 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;
-
- account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
- u_reset_time = account_policy_temp;
-
- account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
- lockout = account_policy_temp;
-
+ account_policy_get(AP_LOCK_ACCOUNT_DURATION, (int *)&u_lock_duration);
+ account_policy_get(AP_RESET_COUNT_TIME, (int *)&u_reset_time);
+ account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &lockout);
+
unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
@@ -2363,8 +2344,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
}
r_u->user_rid=pdb_get_user_rid(sam_pass);
-
- r_u->access_granted = acc_granted;
+ r_u->unknown_0 = 0x000703ff;
pdb_free_sam(&sam_pass);
@@ -2454,56 +2434,6 @@ NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u
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->pipe_user.nt_user_token,
- des_access, &acc_granted, "_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;
-}
-
/**********************************************************************
api_samr_lookup_domain
**********************************************************************/
@@ -4250,8 +4180,6 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
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;
@@ -4267,20 +4195,11 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
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;
+ account_policy_get(AP_MIN_PASSWORD_LEN, &min_pass_len);
+ account_policy_get(AP_PASSWORD_HISTORY, &pass_hist);
+ account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &flag);
+ account_policy_get(AP_MAX_PASSWORD_AGE, (int *)&u_expire);
+ account_policy_get(AP_MIN_PASSWORD_AGE, (int *)&u_min_age);
unix_to_nt_time_abs(&nt_expire, u_expire);
unix_to_nt_time_abs(&nt_min_age, u_min_age);
@@ -4312,9 +4231,7 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
num_users, num_groups, num_aliases);
break;
case 0x03:
- account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
- u_logout = account_policy_temp;
-
+ account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
unix_to_nt_time_abs(&nt_logout, u_logout);
init_unk_info3(&ctr->info.inf3, nt_logout);
@@ -4329,14 +4246,9 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
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;
-
- account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
- u_reset_time = account_policy_temp;
-
- account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
- lockout = account_policy_temp;
+ account_policy_get(AP_LOCK_ACCOUNT_DURATION, (int *)&u_lock_duration);
+ account_policy_get(AP_RESET_COUNT_TIME, (int *)&u_reset_time);
+ account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &lockout);
unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index 5924c5831b..6e3463e79b 100755
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -1515,65 +1515,6 @@ static BOOL api_spoolss_deleteprinterdriverex(pipes_struct *p)
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
@@ -1632,10 +1573,6 @@ struct api_struct api_spoolss_cmds[] =
{"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
{ NULL, 0, NULL }
};
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 2c1dbefd8b..68c792f8b0 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -65,7 +65,7 @@ typedef struct _Printer{
struct _Printer *prev, *next;
BOOL document_started;
BOOL page_started;
- uint32 jobid; /* jobid in printing backend */
+ int jobid; /* jobid in printing backend */
BOOL printer_type;
union {
fstring handlename;
@@ -101,7 +101,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;
@@ -184,7 +184,7 @@ static void srv_spoolss_replycloseprinter(POLICY_HND *handle)
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",
@@ -192,9 +192,9 @@ static void srv_spoolss_replycloseprinter(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);
+ cli_nt_session_close(&cli);
+ cli_ulogoff(&cli);
+ cli_shutdown(&cli);
message_deregister(MSG_PRINTER_NOTIFY2);
}
@@ -668,21 +668,21 @@ struct notify2_message_table {
};
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 },
+ /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", NULL },
+ /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", NULL },
+ /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", NULL },
+ /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", NULL },
+ /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", NULL },
+ /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", NULL },
+ /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", NULL },
/* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
- /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
- /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
+ /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", NULL },
+ /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", NULL },
/* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
- /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
+ /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", NULL },
/* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
- /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
- /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
+ /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", NULL },
+ /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", NULL },
/* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
/* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
/* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
@@ -726,8 +726,6 @@ static void process_notify2_message(struct spoolss_notify_msg *msg,
{
Printer_entry *p;
- DEBUG(8,("process_notify2_message: Enter...[%s]\n", msg->printer));
-
for (p = printers_list; p; p = p->next) {
SPOOL_NOTIFY_INFO_DATA *data;
uint32 data_len = 1;
@@ -738,52 +736,28 @@ static void process_notify2_message(struct spoolss_notify_msg *msg,
if (!p->notify.client_connected)
continue;
- DEBUG(10,("Client connected! [%s]\n", p->dev.handlename));
-
/* For this printer? Print servers always receive
notifications. */
- if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) &&
- ( !strequal(msg->printer, p->dev.handlename) ) )
+ if (p->printer_type == PRINTER_HANDLE_IS_PRINTER &&
+ !strequal(msg->printer, p->dev.handlename))
continue;
- DEBUG(10,("Our printer\n"));
-
/* Are we monitoring this event? */
if (!is_monitoring_event(p, msg->type, msg->field))
continue;
- DEBUG(10,("process_notify2_message: Sending message type [%x] field [%x] for printer [%s]\n",
- msg->type, msg->field, p->dev.handlename));
-
/* OK - send the event to the client */
data = talloc(mem_ctx, sizeof(SPOOL_NOTIFY_INFO_DATA));
ZERO_STRUCTP(data);
- /*
- * 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
- */
+ /* Convert unix jobid to smb jobid */
- if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
- id = 0;
- else
id = msg->id;
-
- /* Convert unix jobid to smb jobid */
-
if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
id = sysjob_to_jobid(msg->id);
@@ -798,31 +772,51 @@ static void process_notify2_message(struct spoolss_notify_msg *msg,
switch(msg->type) {
case PRINTER_NOTIFY_TYPE:
- if ( !printer_notify_table[msg->field].fn )
+ if (printer_notify_table[msg->field].fn)
+ printer_notify_table[msg->field].fn(
+ msg, data, mem_ctx);
+ else
goto done;
-
- printer_notify_table[msg->field].fn(msg, data, mem_ctx);
-
break;
-
case JOB_NOTIFY_TYPE:
- if ( !job_notify_table[msg->field].fn )
+ if (job_notify_table[msg->field].fn)
+ job_notify_table[msg->field].fn(
+ msg, data, mem_ctx);
+ else
goto done;
+ break;
+ default:
+ DEBUG(5, ("Unknown notification type %d\n",
+ msg->type));
+ goto done;
+ }
- job_notify_table[msg->field].fn(msg, data, mem_ctx);
+ if (!p->notify.flags)
+ cli_spoolss_rrpcn(
+ &cli, mem_ctx, &p->notify.client_hnd,
+ data_len, data, p->notify.change, 0);
+ else {
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
- break;
+ get_a_printer(&printer, 2, msg->printer);
- default:
- DEBUG(5, ("Unknown notification type %d\n", msg->type));
+ if (!printer) {
+ DEBUG(5, ("unable to load info2 for %s\n",
+ msg->printer));
goto done;
}
- cli_spoolss_rrpcn( &notify_cli, mem_ctx, &p->notify.client_hnd,
- data_len, data, p->notify.change, 0 );
+ /* XXX: This needs to be updated for
+ PRINTER_CHANGE_SET_PRINTER_DRIVER. */
+
+ cli_spoolss_routerreplyprinter(
+ &cli, mem_ctx, &p->notify.client_hnd,
+ 0, printer->info_2->changeid);
+
+ free_a_printer(&printer, 2);
+ }
}
done:
- DEBUG(8,("process_notify2_message: Exit...\n"));
return;
}
@@ -873,6 +867,30 @@ static void receive_notify2_message(int msg_type, pid_t src, void *buf,
talloc_destroy(mem_ctx);
}
+/***************************************************************************
+ Server wrapper for cli_spoolss_routerreplyprinter() since the client
+ function can only send a single change notification at a time.
+
+ FIXME!!! only handles one change currently (PRINTER_CHANGE_SET_PRINTER_DRIVER)
+ --jerry
+ **************************************************************************/
+
+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)
+{
+ WERROR result;
+ uint32 condition = 0x0;
+
+ 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);
+
+ return result;
+}
+
/********************************************************************
Send a message to ourself about new driver being installed
so we can upgrade the information for each printer bound to this
@@ -944,80 +962,6 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
}
/********************************************************************
- 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( &printer, 2, lp_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));
- }
- }
-
- free_a_printer( &printer, 2 );
- }
- }
-
- /* all done */
-
- return;
-}
-
-/********************************************************************
Copy routines used by convert_to_openprinterex()
*******************************************************************/
@@ -1150,6 +1094,8 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
{
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;
@@ -1497,18 +1443,14 @@ BOOL convert_devicemode(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;
@@ -1798,56 +1740,51 @@ static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND
uint8 **data, uint32 *needed, uint32 in_size )
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
- int snum=0;
- Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- REGISTRY_VALUE *val;
- int size = 0;
+ 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 ) {
+ if (!Printer) {
DEBUG(2,("getprinterdata_printer: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
return False;
}
- if ( !get_printer_snum(p, handle, &snum) )
+ if(!get_printer_snum(p, handle, &snum))
return False;
- if ( !W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) )
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return False;
- if ( !(val = get_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, value)) )
- {
+ if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
free_a_printer(&printer, 2);
return False;
}
-
- *type = regval_type( val );
+ free_a_printer(&printer, 2);
DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size));
- if (in_size)
- {
- if ( (*data = (uint8 *)talloc(ctx, in_size * sizeof(uint8))) == NULL )
+ if (in_size) {
+ if((*data = (uint8 *)talloc(ctx, in_size *sizeof(uint8) )) == NULL) {
return False;
+ }
- memset( *data, 0, in_size *sizeof(uint8) );
-
+ memset(*data, 0, in_size *sizeof(uint8));
/* copy the min(in_size, len) */
-
- size = regval_size( val );
- memcpy( *data, regval_data_p(val), (size > in_size) ? in_size : size*sizeof(uint8) );
- }
- else
+ memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8));
+ } else {
*data = NULL;
+ }
- *needed = size;
+ *needed = len;
DEBUG(5,("getprinterdata_printer:copy done\n"));
+ SAFE_FREE(idata);
- free_a_printer(&printer, 2);
return True;
}
@@ -1876,12 +1813,11 @@ 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"));
@@ -1895,16 +1831,13 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
unistr2_to_ascii(value, valuename, sizeof(value)-1);
if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
- found = getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size);
+ found=getprinterdata_printer_server(p->mem_ctx, value, type, data, needed, *out_size);
else
- found = getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size);
+ found= getprinterdata_printer(p, p->mem_ctx, handle, value, type, data, needed, *out_size);
- if ( !found )
- {
+ 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)
return WERR_NOMEM;
@@ -2033,7 +1966,7 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin
fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
- if(!spoolss_connect_to_client(&notify_cli, unix_printer))
+ if(!spoolss_connect_to_client(&cli, unix_printer))
return False;
message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message);
@@ -2041,7 +1974,7 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin
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))
@@ -2816,7 +2749,7 @@ struct s_notify_info_data_table notify_info_data_table[] =
{ 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_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, 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 },
@@ -2863,13 +2796,10 @@ static uint32 size_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) )
- {
- switch(notify_info_data_table[i].size)
- {
+ 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) {
+ switch(notify_info_data_table[i].size) {
case NOTIFY_ONE_VALUE:
case NOTIFY_TWO_VALUE:
return 1;
@@ -2882,9 +2812,6 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field)
case NOTIFY_POINTER:
return 4;
-
- case NOTIFY_SECDESC:
- return 5;
}
}
}
@@ -2939,11 +2866,13 @@ void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16
info_data->field = field;
info_data->reserved = 0;
+ if (type == JOB_NOTIFY_TYPE)
+ info_data->id = id;
+ else
+ info_data->id = 0;
+
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;
-
}
@@ -2975,24 +2904,20 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
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++)
- {
+ 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) )
continue;
- if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL)
- {
+ 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);
@@ -3119,17 +3044,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 ( 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"));
@@ -3139,7 +3063,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;
}
@@ -3237,6 +3161,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);
@@ -3263,10 +3188,8 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
/* We need to keep track of the change value to send back in
RRPCN replies otherwise our updates are ignored. */
- 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 */
@@ -3447,7 +3370,7 @@ static void free_dev_mode(DEVICEMODE *dev)
Create a DEVMODE struct. Returns malloced memory.
****************************************************************************/
-DEVICEMODE *construct_dev_mode(int snum)
+static DEVICEMODE *construct_dev_mode(int snum)
{
char adevice[32];
char aform[32];
@@ -4805,6 +4728,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;
@@ -4869,7 +4793,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);
@@ -4878,11 +4801,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;
}
@@ -4896,6 +4816,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;
@@ -4977,7 +4898,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) {
@@ -4986,10 +4907,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);
r_u->buffer_written = q_u->buffer_size2;
@@ -5228,6 +5147,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.
@@ -5350,12 +5517,6 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
result = WERR_ACCESS_DENIED;
goto done;
}
-
- /* we need to reset all driver init data for all printers
- bound to this driver */
-
- srv_spoolss_reset_printerdata( printer->info_2->drivername );
-
} else {
/*
* When a *new* driver is bound to a printer, the drivername is used to
@@ -5367,9 +5528,6 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
printer->info_2->drivername));
}
-
- DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
- printer->info_2->drivername));
notify_printer_driver(snum, printer->info_2->drivername);
}
}
@@ -5680,6 +5838,8 @@ 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;
@@ -5747,7 +5907,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;
}
@@ -5756,18 +5916,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;
@@ -6026,6 +6186,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;
@@ -6082,6 +6243,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;
@@ -6182,6 +6344,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;
@@ -6477,6 +6640,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;
@@ -6640,6 +6804,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;
@@ -6787,10 +6952,10 @@ WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *
if ( q_u->copy_flags != APD_COPY_NEW_FILES )
return WERR_ACCESS_DENIED;
+ /* just pass the information off to _spoolss_addprinterdriver() */
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;
@@ -6882,38 +7047,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 *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;
+ 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;
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 param_index;
- 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;
- 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"));
@@ -6928,133 +7093,103 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
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 )
- {
+ if ( (in_value_len==0) && (in_data_len==0) ) {
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
- param_index = 0;
- 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
*/
-
- 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;
- }
+ *out_max_value_len=(in_value_len/sizeof(uint16));
+ if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
+ return WERR_NOMEM;
*out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
/* 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);
-
- /* type */
-
- *out_type = regval_type( val );
+ *out_value_len = (uint32)rpcstr_push((char *)*out_value,value, in_value_len, 0);
- /* 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;
}
/****************************************************************************
@@ -7062,17 +7197,17 @@ 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;
+ uint8 *data = q_u->data;
+ uint32 real_len = q_u->real_len;
- 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"));
@@ -7084,6 +7219,8 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
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.
@@ -7098,22 +7235,40 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
goto done;
}
+ /* 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;
- /* save the registry data */
-
- unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
- delete_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename );
- add_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename, type, data, real_len );
+ convert_specific_param(&param, value , type, data, real_len);
- /* write the **entire** printer out to disk.... :-( */
+ unlink_specific_param_if_exist(printer->info_2, param);
- status = mod_a_printer(*printer, 2);
+ /*
+ * 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 (param->type==3 && !strcmp( param->value, PHANTOM_DEVMODE_KEY)) {
+ /*
+ * Set devmode and printer initialization info
+ */
+ status = save_driver_init(printer, 2, param);
+ }
+ 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;
}
@@ -7123,9 +7278,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"));
@@ -7149,19 +7304,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"));
@@ -7182,14 +7334,15 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
if (!W_ERROR_IS_OK(status))
return status;
- unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
+ ZERO_STRUCTP(&param);
+ unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
- status = delete_printer_data( printer->info_2, SPOOL_PRINTERDATA_KEY, valuename );
- if ( NT_STATUS_IS_OK(status) )
+ 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;
}
@@ -7199,6 +7352,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;
@@ -7817,10 +7971,9 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u,
* (a) DsDriver
* (b) DsSpooler
* (c) PnPData
- * (d) DsUser
*/
- if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0)
+ if (strcmp(key, "PrinterDriverData") != 0)
return WERR_BADFILE;
DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n"));
@@ -7866,7 +8019,7 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
- if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0)
+ if (strcmp(key, "PrinterDriverData") != 0)
return WERR_INVALID_PARAM;
ZERO_STRUCT(q_u_local);
@@ -7901,7 +8054,7 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
- if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0)
+ if (strcmp(key, "PrinterDriverData") != 0)
return WERR_INVALID_PARAM;
memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND));
@@ -7917,66 +8070,57 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
* 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;
- uint16 *enumkeys = NULL;
+ uint16 enumkeys[ENUMERATED_KEY_SIZE+1];
char* ptr = NULL;
int i;
- int printerkey_len = strlen(SPOOL_PRINTERDATA_KEY)+1;
+ char *PrinterKey = "PrinterDriverData";
DEBUG(4,("_spoolss_enumprinterkey\n"));
- unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 );
+ unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
/*
* we only support enumating all keys (key == "")
* Of course, the only key we support is the "PrinterDriverData"
* key
- */
-
- if ( !strlen( key ) )
+ */
+ if (strlen(key) == 0)
{
- r_u->needed = printerkey_len*2;
-
- if ( q_u->size < r_u->needed )
+ r_u->needed = ENUMERATED_KEY_SIZE *2;
+ if (q_u->size < r_u->needed)
return WERR_MORE_DATA;
- if ( !(enumkeys = talloc( p->mem_ctx, printerkey_len*2 )) ) {
- DEBUG(0,("_spoolss_enumprinterkey: talloc() failed for [%d] bytes!\n",
- printerkey_len));
- return WERR_NOMEM;
- }
-
- ptr = SPOOL_PRINTERDATA_KEY;
- for ( i=0; i<(printerkey_len-1); i++ )
+ ptr = PrinterKey;
+ for (i=0; i<ENUMERATED_KEY_SIZE-2; i++)
{
enumkeys[i] = (uint16)(*ptr);
ptr++;
}
- /* tag of '\0's */
-
- enumkeys[i] = 0x0;
+ /* tag of with 2 '\0's */
+ enumkeys[i++] = '\0';
+ enumkeys[i] = '\0';
- if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys))
+ if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, ENUMERATED_KEY_SIZE, enumkeys))
return WERR_BADFILE;
return WERR_OK;
}
/* The "PrinterDriverData" key should have no subkeys */
- if ( strcmp(key, SPOOL_PRINTERDATA_KEY) == 0 )
+ if (strcmp(key, PrinterKey) == 0)
{
- uint16 dummy_key = 0;
-
- r_u->needed = 2;
-
+ r_u-> needed = 2;
if (q_u->size < r_u->needed)
return WERR_MORE_DATA;
-
- if ( !make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, &dummy_key ) )
+ enumkeys[0] = 0x0;
+ if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, enumkeys))
return WERR_BADFILE;
return WERR_OK;
@@ -7985,7 +8129,6 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO
/* The return value for an unknown key is documented in MSDN
EnumPrinterKey description */
-
return WERR_BADFILE;
}
@@ -8005,7 +8148,7 @@ WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u,
unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
- if (strcmp(key, SPOOL_PRINTERDATA_KEY) != 0)
+ if (strcmp(key, "PrinterDriverData") != 0)
return WERR_INVALID_PARAM;
/*
@@ -8029,16 +8172,14 @@ 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"));
@@ -8049,8 +8190,20 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
}
- /* first get the printer off of disk */
-
+ /*
+ * 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 (strcmp(key, "PrinterDriverData") != 0)
+ {
+ DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
+ return WERR_INVALID_PARAM;
+ }
+
+
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
@@ -8058,78 +8211,55 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
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;
+ uint32 add_len = 0;
+
+ 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 [%d] bytes!\n",
- 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 */
-
- val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
- DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
+ enum_values = ptr;
/* copy the data */
+ init_unistr(&enum_values[num_entries].valuename, value);
+ enum_values[num_entries].value_len = (strlen(value)+1) * 2;
+ enum_values[num_entries].type = type;
- 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 );
-
- 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 ));
- result = WERR_NOMEM;
- goto done;
- }
+ if (!(enum_values[num_entries].data=talloc_zero(p->mem_ctx, data_len+add_len))) {
+ DEBUG(0,("talloc_realloc failed to allocate more memory for data!\n"));
+ result = WERR_NOMEM;
+ goto done;
}
- enum_values[i].data_len = data_len;
+ memcpy(enum_values[num_entries].data, data, data_len);
+ enum_values[num_entries].data_len = data_len + add_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;
@@ -8225,23 +8355,4 @@ 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/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c
index 4a372de089..5e1c005d54 100644
--- a/source3/rpc_server/srv_srvsvc.c
+++ b/source3/rpc_server/srv_srvsvc.c
@@ -345,36 +345,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
********************************************************************/
@@ -533,7 +503,6 @@ static const struct api_struct api_srv_cmds[] =
{ "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 },
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 5c1038949b..202e869d35 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -3,7 +3,6 @@
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-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
@@ -30,53 +29,32 @@
extern pstring global_myname;
/*******************************************************************
- 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);
-}
-
-/*******************************************************************
Fill in a share info level 1 structure.
********************************************************************/
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));
+ 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);
}
@@ -86,11 +64,14 @@ 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));
pstrcpy(path, "C:");
@@ -104,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);
}
@@ -259,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)
@@ -345,7 +337,7 @@ BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, u
ret = se_access_check(psd, token, desired_access, &granted, &status);
-out:
+ out:
talloc_destroy(mem_ctx);
@@ -359,15 +351,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));
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);
}
@@ -382,6 +386,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;
@@ -405,86 +410,39 @@ 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->dfs_root_flag = 0;
if(lp_host_msdfs() && lp_msdfs_root(snum))
sh1005->dfs_root_flag = 3;
}
-/***************************************************************************
- 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);
-
- 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)
{
pstring net_name;
@@ -513,7 +471,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 +483,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 +491,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 +508,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 +525,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 +542,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 +551,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 +596,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 +608,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));
@@ -1120,8 +955,7 @@ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
********************************************************************/
static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
- int switch_value, uint32 *resume_hnd,
- uint32 *total_entries)
+ int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
WERROR status = WERR_OK;
TALLOC_CTX *ctx = p->mem_ctx;
@@ -1372,8 +1206,8 @@ WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET
/* 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__));
@@ -1461,7 +1295,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
unistr2_to_ascii(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;
@@ -1478,47 +1312,28 @@ 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:
- fstrcpy(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_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));
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_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));
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:
- fstrcpy(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:
- case 1006:
- case 1007:
return WERR_ACCESS_DENIED;
- break;
case 1501:
fstrcpy(pathname, lp_pathname(snum));
fstrcpy(comment, lp_comment(snum));
@@ -1607,12 +1422,12 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
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;
}
@@ -1622,9 +1437,6 @@ 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;
@@ -1634,9 +1446,6 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
unistr2_to_ascii(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));
@@ -1645,16 +1454,7 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
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:
@@ -1744,7 +1544,7 @@ 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())
@@ -1770,13 +1570,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
********************************************************************/
@@ -1910,7 +1703,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);
@@ -2006,7 +1799,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);
@@ -2071,7 +1864,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;
@@ -2080,18 +1872,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*/
@@ -2105,7 +1885,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++;
diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c
index 50bf5db4fd..f896d1d9d8 100644
--- a/source3/rpc_server/srv_util.c
+++ b/source3/rpc_server/srv_util.c
@@ -84,10 +84,10 @@ rid_name domain_group_rids[] =
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;
+ struct sys_grent *glist;
+ struct sys_grent *grp;
+ int i, num, cur_rid=0;
gid_t gid;
- gid_t *groups = NULL;
- int num_groups;
GROUP_MAP map;
DOM_SID tmp_sid;
fstring user_name;
@@ -130,21 +130,16 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
fstrcpy(user_name, pdb_get_username(sam_pass));
grid=pdb_get_group_rid(sam_pass);
gid=pdb_get_gid(sam_pass);
-
- 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"));
+
+ grp = glist = getgrent_list();
+ if (grp == NULL) {
pdb_free_sam(&sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_NO_MEMORY;
}
-
- for (i=0;i<num_groups;i++) {
- if(!get_group_from_gid(groups[i], &map, MAPPING_WITHOUT_PRIV)) {
- DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)groups[i]));
+
+ for (; grp != NULL; grp = grp->next) {
+ if(!get_group_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)) {
+ DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)grp->gr_gid));
continue;
}
@@ -164,7 +159,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
}
/* Don't return winbind groups as they are not local! */
- if (winbind_groups_exist && (groups[i] >= winbind_gid_low) && (groups[i] <= winbind_gid_high)) {
+ if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low) && (grp->gr_gid <= winbind_gid_high)) {
DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name));
continue;
}
@@ -175,21 +170,30 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
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;
+ /* the group is fine, we can check if there is the user we're looking for */
+ DEBUG(10,("get_alias_user_groups: checking if the user is a member of %s.\n", map.nt_name));
- sid_peek_rid(&map.sid, &(rids[cur_rid]));
- cur_rid++;
- break;
+ 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 */
+
+ 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]));
+ DEBUG(10,("get_alias_user_groups: user found in group %s\n", map.nt_name));
+ cur_rid++;
+ break;
+ }
+ }
}
- free(groups);
+ grent_free(glist);
/* now check for the user's gid (the primary group rid) */
for (i=0; i<cur_rid && grid!=rids[i]; i++)
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c
index 194e498122..067325c06e 100644
--- a/source3/rpcclient/cmd_lsarpc.c
+++ b/source3/rpcclient/cmd_lsarpc.c
@@ -32,8 +32,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
DOM_SID dom_sid;
- GUID dom_guid;
- fstring sid_str, domain_name="", dns_name="", forest_name="";
+ fstring sid_str, domain_name;
uint32 info_class = 3;
if (argc > 2) {
@@ -44,31 +43,17 @@ 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;
@@ -80,22 +65,6 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
else
printf("could not query info for level %d\n", info_class);
- if (dns_name[0])
- printf("domain dns name is %s\n", dns_name);
- if (forest_name[0])
- printf("forest name is %s\n", forest_name);
-
- if (info_class == 12) {
- int i;
- uint32 *data1 = (uint32 *) dom_guid.info;
- uint16 *data2 = (uint16 *) &dom_guid.info[4];
- uint16 *data3 = (uint16 *) &dom_guid.info[6];
- printf("domain GUID is %08x-%04x-%04x", *data1,*data2,*data3);
- printf("-%02x%02x-", dom_guid.info[8], dom_guid.info[9]);
- for (i=10;i<GUID_SIZE;i++)
- printf("%02x", dom_guid.info[i]);
- printf("\n");
- }
done:
return result;
}
@@ -222,15 +191,23 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
/* defaults, but may be changed using params */
uint32 enum_ctx = 0;
+ uint32 preferred_maxnum = 5;
uint32 num_domains = 0;
int i;
- if (argc > 2) {
- printf("Usage: %s [enum context (0)]\n", argv[0]);
+ if (argc > 3) {
+ printf("Usage: %s [preferred max number (%d)] [enum context (0)]\n",
+ argv[0], preferred_maxnum);
return NT_STATUS_OK;
}
- if (argc == 2 && argv[1]) {
+ /* enumeration context */
+ if (argc >= 2 && argv[1]) {
+ preferred_maxnum = atoi(argv[1]);
+ }
+
+ /* preferred maximum number */
+ if (argc == 3 && argv[2]) {
enum_ctx = atoi(argv[2]);
}
@@ -244,8 +221,8 @@ 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);
+ &preferred_maxnum, &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))
diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c
index c3bc9e5e13..2e89572660 100644
--- a/source3/rpcclient/cmd_netlogon.c
+++ b/source3/rpcclient/cmd_netlogon.c
@@ -174,7 +174,7 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
goto done;
}
- result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
@@ -238,7 +238,7 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
goto done;
}
- result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
@@ -301,7 +301,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
goto done;
}
- result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index d9251f90bd..eae24683d2 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -243,22 +243,6 @@ 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
*/
@@ -291,8 +275,8 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
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;
@@ -399,8 +383,8 @@ static NTSTATUS cmd_samr_query_group(struct cli_state *cli,
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;
@@ -463,8 +447,8 @@ static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
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;
@@ -529,8 +513,8 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
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;
@@ -592,8 +576,8 @@ static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
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;
@@ -651,8 +635,8 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli,
/* Get sam policy handle */
- 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;
@@ -727,8 +711,8 @@ static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
/* Get sam policy handle */
- 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;
@@ -810,8 +794,8 @@ static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
/* Open SAMR handle */
- 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;
@@ -894,8 +878,7 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
/* Get sam policy handle */
- 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;
@@ -1000,8 +983,8 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
/* Get sam policy handle */
- 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;
@@ -1070,8 +1053,8 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
/* Get sam policy handle */
- 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;
@@ -1126,8 +1109,8 @@ 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))
goto done;
@@ -1191,8 +1174,8 @@ 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))
goto done;
@@ -1248,8 +1231,8 @@ static NTSTATUS cmd_samr_delete_dom_user(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))
goto done;
@@ -1329,8 +1312,8 @@ static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
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;
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index 22e2db41f3..47e3f123ba 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -1796,85 +1796,6 @@ done:
return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-static NTSTATUS cmd_spoolss_rffpcnex(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc,
- 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(fstring) - 1, "\\\\%s", cli->desthost);
- strupper(servername);
-
- slprintf(printername, sizeof(fstring) - 1, "\\\\%s\\%s", cli->desthost,
- argv[1]);
- strupper(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(fstring) - 1, "\\\\%s", myhostname());
- strupper(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 W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
/* List of commands exported by this module */
struct cmd_set spoolss_commands[] = {
@@ -1903,7 +1824,6 @@ struct cmd_set spoolss_commands[] = {
{ "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", "" },
- { "rffpcnex", cmd_spoolss_rffpcnex, PIPE_SPOOLSS, "Rffpcnex test", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_srvsvc.c b/source3/rpcclient/cmd_srvsvc.c
index 8d416f8db0..43bfb25048 100644
--- a/source3/rpcclient/cmd_srvsvc.c
+++ b/source3/rpcclient/cmd_srvsvc.c
@@ -270,7 +270,7 @@ static NTSTATUS cmd_srvsvc_net_share_enum(struct cli_state *cli,
result = cli_srvsvc_net_share_enum(
cli, mem_ctx, info_level, &ctr, preferred_len, &hnd);
- if (!W_ERROR_IS_OK(result) || !ctr.num_entries)
+ if (!W_ERROR_IS_OK(result))
goto done;
/* Display results */
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 2d86fb1d3d..a62c3d8365 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -612,6 +612,7 @@ static void usage(void)
*opt_configfile=NULL,
*opt_logfile=NULL,
*opt_ipaddr=NULL;
+ static int opt_debuglevel;
pstring logfile;
struct cmd_set **cmd_set;
struct in_addr server_ip;
@@ -625,13 +626,14 @@ static void usage(void)
{"authfile", 'A', POPT_ARG_STRING, &opt_authfile, 'A'},
{"conf", 's', POPT_ARG_STRING, &opt_configfile, 's'},
{"nopass", 'N', POPT_ARG_NONE, &got_pass},
+ {"debug", 'd', POPT_ARG_INT, &opt_debuglevel, 'd'},
+ {"debuglevel", 'd', POPT_ARG_INT, &opt_debuglevel, 'd'},
{"user", 'U', POPT_ARG_STRING, &opt_username, 'U'},
{"workgroup", 'W', POPT_ARG_STRING, &opt_domain, 'W'},
{"command", 'c', POPT_ARG_STRING, &cmdstr},
{"logfile", 'l', POPT_ARG_STRING, &opt_logfile, 'l'},
{"help", 'h', POPT_ARG_NONE, 0, 'h'},
{"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I'},
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug },
{ NULL }
};
@@ -671,6 +673,10 @@ static void usage(void)
pstrcpy(dyn_CONFIGFILE, opt_configfile);
break;
+ case 'd':
+ DEBUGLEVEL = opt_debuglevel;
+ break;
+
case 'U': {
char *lp;
@@ -762,7 +768,7 @@ static void usage(void)
password, 0);
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;
}
diff --git a/source3/rpcclient/samsync.c b/source3/rpcclient/samsync.c
index 3694eb47df..5b64cbc47d 100644
--- a/source3/rpcclient/samsync.c
+++ b/source3/rpcclient/samsync.c
@@ -1,8 +1,8 @@
/*
Unix SMB/CIFS implementation.
- SAM synchronisation and replication
+ RPC pipe client
- Copyright (C) Tim Potter 2001,2002
+ 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
@@ -21,8 +21,6 @@
#include "includes.h"
-DOM_SID domain_sid;
-
static void decode_domain_info(SAM_DOMAIN_INFO *a)
{
fstring temp;
@@ -254,124 +252,20 @@ static void decode_sam_deltas(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas, SAM_
}
}
-/* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */
-
-static void sam_account_from_delta(SAM_ACCOUNT *account,
- SAM_ACCOUNT_INFO *delta)
-{
- DOM_SID sid;
- fstring s;
-
- /* Username, fullname, home dir, dir drive, logon script, acct
- desc, workstations, profile. */
-
- unistr2_to_ascii(s, &delta->uni_acct_name, sizeof(s) - 1);
- pdb_set_nt_username(account, s);
-
- /* Unix username is the same - for sainity */
- pdb_set_username(account, s);
-
- unistr2_to_ascii(s, &delta->uni_full_name, sizeof(s) - 1);
- pdb_set_fullname(account, s);
-
- unistr2_to_ascii(s, &delta->uni_home_dir, sizeof(s) - 1);
- pdb_set_homedir(account, s, True);
-
- unistr2_to_ascii(s, &delta->uni_dir_drive, sizeof(s) - 1);
- pdb_set_dir_drive(account, s, True);
-
- unistr2_to_ascii(s, &delta->uni_logon_script, sizeof(s) - 1);
- pdb_set_logon_script(account, s, True);
-
- unistr2_to_ascii(s, &delta->uni_acct_desc, sizeof(s) - 1);
- pdb_set_acct_desc(account, s);
-
- unistr2_to_ascii(s, &delta->uni_workstations, sizeof(s) - 1);
- pdb_set_workstations(account, s);
-
- unistr2_to_ascii(s, &delta->uni_profile, sizeof(s) - 1);
- pdb_set_profile_path(account, s, True);
-
- /* User and group sid */
-
- sid_copy(&sid, &domain_sid);
- sid_append_rid(&sid, delta->user_rid);
- pdb_set_user_sid(account, &sid);
-
- sid_copy(&sid, &domain_sid);
- sid_append_rid(&sid, delta->group_rid);
- pdb_set_group_sid(account, &sid);
-
- /* Logon and password information */
-
- pdb_set_logon_time(account, nt_time_to_unix(&delta->logon_time), True);
- pdb_set_logoff_time(account, nt_time_to_unix(&delta->logoff_time),
- True);
-
- pdb_set_logon_divs(account, delta->logon_divs);
-
- /* TODO: logon hours */
- /* TODO: bad password count */
- /* TODO: logon count */
-
- pdb_set_pass_last_set_time(
- account, nt_time_to_unix(&delta->pwd_last_set_time));
-
- /* TODO: account expiry time */
-
- pdb_set_acct_ctrl(account, delta->acb_info);
-}
-
-static void apply_account_info(SAM_ACCOUNT_INFO *sam_acct_delta)
-{
- SAM_ACCOUNT sam_acct;
- BOOL result;
-
- ZERO_STRUCT(sam_acct);
-
- pdb_init_sam(&sam_acct);
-
- sam_account_from_delta(&sam_acct, sam_acct_delta);
- result = pdb_add_sam_account(&sam_acct);
-}
-
-/* Apply an array of deltas to the SAM database */
-
-static void apply_deltas(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas,
- SAM_DELTA_CTR *deltas)
-{
- uint32 i;
-
- for (i = 0; i < num_deltas; i++) {
- switch(hdr_deltas[i].type) {
- case SAM_DELTA_ACCOUNT_INFO:
- apply_account_info(&deltas[i].account_info);
- break;
- }
- }
-}
-
/* Synchronise sam database */
static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16],
BOOL do_smbpasswd_output, BOOL verbose)
{
TALLOC_CTX *mem_ctx;
- SAM_DELTA_HDR *hdr_deltas_0, *hdr_deltas_2;
- SAM_DELTA_CTR *deltas_0, *deltas_2;
- uint32 num_deltas_0, num_deltas_2;
+ SAM_DELTA_HDR *hdr_deltas_0, *hdr_deltas_1, *hdr_deltas_2;
+ SAM_DELTA_CTR *deltas_0, *deltas_1, *deltas_2;
+ uint32 num_deltas_0, num_deltas_1, num_deltas_2;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- struct pdb_context *in;
DOM_CRED ret_creds;
-
/* Initialise */
- if (!NT_STATUS_IS_OK(make_pdb_context_list(&in, lp_passdb_backend()))){
- DEBUG(0, ("Can't initialize passdb backend.\n"));
- return result;
- }
-
if (!(mem_ctx = talloc_init())) {
DEBUG(0,("talloc_init failed\n"));
return result;
@@ -384,7 +278,7 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16],
/* Request a challenge */
- if (!NT_STATUS_IS_OK(cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_passwd))) {
+ if (!NT_STATUS_IS_OK(new_cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_passwd))) {
DEBUG(0, ("Error initialising session creds\n"));
goto done;
}
@@ -394,14 +288,14 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16],
/* Do sam synchronisation on the SAM database*/
- result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, 0,
- &num_deltas_0, &hdr_deltas_0,
- &deltas_0);
+ result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, 0, &num_deltas_0, &hdr_deltas_0, &deltas_0);
if (!NT_STATUS_IS_OK(result))
goto done;
- apply_deltas(num_deltas_0, hdr_deltas_0, deltas_0);
+ /* verbose mode */
+ if (verbose)
+ decode_sam_deltas(num_deltas_0, hdr_deltas_0, deltas_0);
/*
@@ -485,6 +379,23 @@ static NTSTATUS sam_repl(struct cli_state *cli, unsigned char trust_passwde[16],
return result;
}
+/* Print usage information */
+
+static void usage(void)
+{
+ printf("Usage: samsync [options]\n");
+
+ 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("\t-V verbose output\n");
+ printf("\n");
+}
+
/* Connect to primary domain controller */
static struct cli_state *init_connection(struct cli_state **cli,
@@ -496,16 +407,7 @@ static struct cli_state *init_connection(struct cli_state **cli,
int count;
fstring dest_host;
- /* Initialise myname */
-
- if (!global_myname[0]) {
- char *p;
-
- fstrcpy(global_myname, myhostname());
- p = strchr(global_myname, '.');
- if (p)
- *p = 0;
- }
+ /* Initialise cli_state information */
/* Look up name of PDC controller */
@@ -528,239 +430,148 @@ static struct cli_state *init_connection(struct cli_state **cli,
username, domain,
password, 0))) {
return *cli;
+ } else {
+ return NULL;
}
-
- return NULL;
}
/* Main function */
-static fstring popt_username, popt_domain, popt_password;
-static BOOL popt_got_pass;
-
-static void user_callback(poptContext con,
- enum poptCallbackReason reason,
- const struct poptOption *opt,
- const char *arg, const void *data)
-{
- char *p, *ch;
-
- if (!arg)
- return;
-
- switch(opt->val) {
-
- /* Check for [DOMAIN\\]username[%password]*/
-
- case 'U':
-
- p = arg;
-
- if ((ch = strchr(p, '\\'))) {
- fstrcpy(popt_domain, p);
- popt_domain[ch - p] = 0;
- }
-
- fstrcpy(popt_username, p);
-
- if ((ch = strchr(p, '%'))) {
- popt_username[ch - p] = 0;
- fstrcpy(popt_password, ch + 1);
- popt_got_pass = True;
- }
-
- break;
-
- case 'W':
- fstrcpy(popt_domain, arg);
- break;
- }
-}
-
-/* Return domain, username and password passed in from cmd line */
-
-void popt_common_get_auth_info(char **domain, char **username, char **password,
- BOOL *got_pass)
-{
- *domain = popt_domain;
- *username = popt_username;
- *password = popt_password;
- *got_pass = popt_got_pass;
-}
-
-struct poptOption popt_common_auth_info[] = {
- { NULL, 0, POPT_ARG_CALLBACK, user_callback },
- { "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set username",
- "[DOMAIN\\]username[%password]" },
- { "domain", 'W', POPT_ARG_STRING, NULL, 'W', "Set domain name",
- "DOMAIN"},
- { 0 }
-};
-
-static BOOL popt_interactive;
-
-BOOL popt_common_is_interactive(void)
-{
- return popt_interactive;
-}
-
-struct poptOption popt_common_interactive[] = {
- { "interactive", 'i', POPT_ARG_NONE, &popt_interactive, 'i',
- "Log to stdout" },
- { 0 }
-};
-
int main(int argc, char **argv)
{
BOOL do_sam_sync = False, do_sam_repl = False;
struct cli_state *cli;
NTSTATUS result;
+ int opt;
pstring logfile;
- BOOL do_smbpasswd_output = False;
- BOOL verbose = True, got_pass = False;
- uint32 serial = 0;
+ BOOL interactive = False, do_smbpasswd_output = False;
+ BOOL verbose = False;
+ uint32 low_serial = 0;
unsigned char trust_passwd[16];
- char *username, *domain, *password;
- poptContext pc;
- char c;
-
- struct poptOption popt_samsync_opts[] = {
- { "synchronise", 'S', POPT_ARG_NONE, &do_sam_sync, 'S',
- "Perform full SAM synchronisation" },
- { "replicate", 'R', POPT_ARG_NONE, &do_sam_repl, 'R',
- "Replicate SAM changes" },
- { "serial", 0, POPT_ARG_INT, &serial, 0, "SAM serial number" },
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug },
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_auth_info },
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_interactive },
- POPT_AUTOHELP
- { 0 }
- };
-
- /* Read command line options */
-
- pc = poptGetContext("samsync", argc, (const char **)argv,
- popt_samsync_opts, 0);
-
- if (argc == 1) {
- poptPrintUsage(pc, stdout, 0);
- return 1;
- }
-
- while ((c = poptGetNextOpt(pc)) != -1) {
-
- /* Argument processing error */
-
- if (c < -1) {
- fprintf(stderr, "samsync: %s: %s\n",
- poptBadOption(pc, POPT_BADOPTION_NOALIAS),
- poptStrerror(c));
- return 1;
- }
-
- /* Handle arguments */
+ fstring username, domain, password;
- switch (c) {
- case 'h':
- poptPrintHelp(pc, stdout, 0);
- return 1;
- case 'u':
- poptPrintUsage(pc, stdout, 0);
- return 1;
- }
- }
-
- /* Bail out if any extra args were passed */
+ if (argc == 1) {
+ usage();
+ return 1;
+ }
- if (poptPeekArg(pc)) {
- fprintf(stderr, "samsync: invalid argument %s\n",
- poptPeekArg(pc));
- poptPrintUsage(pc, stdout, 0);
- 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:pV")) != EOF) {
+ switch (opt) {
+ case 's':
+ pstrcpy(dyn_CONFIGFILE, 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_m(username,'%'))) {
+ *lp = 0;
+ fstrcpy(password,lp+1);
+ memset(strchr_m(optarg, '%') + 1, 'X',
+ strlen(password));
+ }
+ break;
+ }
+ case 'W':
+ pstrcpy(domain, optarg);
+ break;
+ case 'p':
+ do_smbpasswd_output = True;
+ break;
+ case 'V':
+ verbose = True;
+ break;
+ case 'h':
+ default:
+ usage();
+ exit(1);
+ }
+ }
- poptFreeContext(pc);
+ argc -= optind;
- /* Setup logging */
+ if (argc > 0) {
+ usage();
+ return 1;
+ }
- dbf = x_stdout;
-
- if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
- d_fprintf(stderr, "samsync: error opening config file %s. "
- "Error was %s\n", dyn_CONFIGFILE, strerror(errno));
- return 1;
- }
+ /* Initialise samba */
slprintf(logfile, sizeof(logfile) - 1, "%s/log.%s", dyn_LOGFILEBASE,
"samsync");
-
lp_set_logfile(logfile);
- setup_logging("samsync", popt_common_is_interactive());
+ setup_logging("samsync", interactive);
- if (!popt_common_is_interactive())
+ if (!interactive)
reopen_logs();
- load_interfaces();
+ if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
+ fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
+ }
+
+ load_interfaces();
/* Check arguments make sense */
if (do_sam_sync && do_sam_repl) {
- DEBUG(0, ("cannot specify both -S and -R\n"));
+ fprintf(stderr, "cannot specify both -S and -R\n");
return 1;
}
if (!do_sam_sync && !do_sam_repl) {
- DEBUG(0, ("samsync: you must either --synchronise or "
- "--replicate the SAM database\n"));
+ fprintf(stderr, "must specify either -S or -R\n");
return 1;
}
- if (do_sam_repl && serial == 0) {
- DEBUG(0, ("samsync: must specify serial number\n"));
+ if (do_sam_repl && low_serial == 0) {
+ fprintf(stderr, "serial number must be positive\n");
return 1;
}
- if (do_sam_sync && serial != 0) {
- DEBUG(0, ("samsync: you can't specify a serial number when "
- "synchonising the SAM database\n"));
- return 1;
- }
-
/* BDC operations require the machine account password */
if (!secrets_init()) {
- DEBUG(0, ("samsync: unable to initialise secrets database\n"));
+ DEBUG(0, ("Unable to initialise secrets database\n"));
return 1;
}
if (!secrets_fetch_trust_account_password(lp_workgroup(),
trust_passwd, NULL)) {
- DEBUG(0, ("samsync: could not fetch trust account password\n"));
+ DEBUG(0, ("could not fetch trust account password\n"));
return 1;
}
- /* I wish the domain sid wasn't stored in secrets.tdb */
-
- if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
- DEBUG(0, ("samsync: could not retrieve domain sid\n"));
- return 1;
- }
-
/* Perform sync or replication */
- popt_common_get_auth_info(&domain, &username, &password, &got_pass);
-
if (!init_connection(&cli, username, domain, password))
return 1;
if (do_sam_sync)
- result = sam_sync(cli, trust_passwd, do_smbpasswd_output,
- verbose);
+ result = sam_sync(cli, trust_passwd, do_smbpasswd_output, verbose);
if (do_sam_repl)
- result = sam_repl(cli, trust_passwd, serial);
+ result = sam_repl(cli, trust_passwd, low_serial);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0, ("%s\n", nt_errstr(result)));
diff --git a/source3/script/installman.sh b/source3/script/installman.sh
index 5b6bba69ed..2329ed5425 100755
--- a/source3/script/installman.sh
+++ b/source3/script/installman.sh
@@ -22,8 +22,8 @@ for lang in $langs; do
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
+ langdir=$MANDIR/lang/$lang
+ for d in $MANDIR $MANDIR/lang $langdir $langdir/man1 $langdir/man5 $langdir/man7 $langdir/man8; do
if [ ! -d $d ]; then
mkdir $d
if [ ! -d $d ]; then
diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk
index 196715d6b1..c701ed41cd 100644
--- a/source3/script/mkproto.awk
+++ b/source3/script/mkproto.awk
@@ -142,7 +142,7 @@ END {
gotstart = 1;
}
- if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^ADS_MODLIST|^PyObject|^SORTED_TREE|^REGISTRY_HOOK|^REGISTRY_VALUE|^DEVICEMODE/ ) {
+ if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^ADS_MODLIST|^PyObject/ ) {
gotstart = 1;
}
diff --git a/source3/script/mkproto.sh b/source3/script/mkproto.sh
index 2bf96c9b41..4dbe4c204e 100755
--- a/source3/script/mkproto.sh
+++ b/source3/script/mkproto.sh
@@ -29,8 +29,6 @@ proto_src="`echo $@ | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort | uniq | egrep -
echo creating $header
-mkdir -p `dirname $header`
-
${awk} $headeropt \
-f script/mkproto.awk $proto_src > $headertmp
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 6623c6df64..d4a53d9a6d 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -282,10 +282,9 @@ static BOOL process_lockread(blocking_lock_record *blr)
status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread,
(SMB_BIG_UINT)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)) {
+ if ((errno != EACCES) && (errno != EAGAIN)) {
/*
- * We have other than a "can't get lock"
+ * We have other than a "can't get lock" POSIX
* error. Send an error.
* Return True so we get dequeued.
*/
@@ -349,10 +348,9 @@ static BOOL process_lock(blocking_lock_record *blr)
status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count,
(SMB_BIG_UINT)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)) {
+ if((errno != EACCES) && (errno != EAGAIN)) {
/*
- * We have other than a "can't get lock"
+ * We have other than a "can't get lock" POSIX
* error. Send an error.
* Return True so we get dequeued.
*/
@@ -434,13 +432,12 @@ static BOOL process_lockingX(blocking_lock_record *blr)
reply_lockingX_success(blr);
return True;
- } else if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
- /*
- * We have other than a "can't get lock"
- * error. Free any locks we had and return an error.
- * Return True so we get dequeued.
- */
+ } else if ((errno != EACCES) && (errno != EAGAIN)) {
+ /*
+ * We have other than a "can't get lock" POSIX
+ * error. Free any locks we had and return an error.
+ * Return True so we get dequeued.
+ */
blocking_lock_reply_error(blr, status);
return True;
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 9e593b022e..68871deb90 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -167,17 +167,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);
@@ -196,9 +196,7 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
}
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
stermios.c_lflag |= ICANON;
-#ifdef ONLCR
stermios.c_oflag &= ~(ONLCR);
-#endif
if (tcsetattr(0, TCSANOW, &stermios) < 0)
{
DEBUG(3, ("could not set attributes of pty\n"));
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index d70e50f899..c0aa447016 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -2,7 +2,6 @@
Unix SMB/CIFS implementation.
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
@@ -163,25 +162,11 @@ BOOL conn_idle_all(time_t t, int deadtime)
void conn_free(connection_struct *conn)
{
- smb_vfs_handle_struct *handle, *thandle;
- void (*done_fptr)(connection_struct *the_conn);
-
/* Free vfs_connection_struct */
- handle = conn->vfs_private;
- while(handle) {
- /* Close dlopen() handle */
- done_fptr = (void (*)(connection_struct *))sys_dlsym(handle->handle, "vfs_done");
-
- if (done_fptr == NULL) {
- DEBUG(3, ("No vfs_done() symbol found in module with handle %p, ignoring\n", handle->handle));
- } else {
- done_fptr(conn);
- }
- sys_dlclose(handle->handle);
- DLIST_REMOVE(conn->vfs_private, handle);
- thandle = handle->next;
- SAFE_FREE(handle);
- handle = thandle;
+
+ if (conn->dl_handle != NULL) {
+ /* Close dlopen() handle */
+ sys_dlclose(conn->dl_handle);
}
DLIST_REMOVE(Connections, conn);
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 5609c2963d..c9815dbf8c 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -20,6 +20,7 @@
#include "includes.h"
+extern fstring remote_machine;
static TDB_CONTEXT *tdb;
/****************************************************************************
@@ -28,11 +29,6 @@ static TDB_CONTEXT *tdb;
TDB_CONTEXT *conn_tdb_ctx(void)
{
- if (!tdb) {
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
- O_RDWR | O_CREAT, 0644);
- }
-
return tdb;
}
@@ -177,7 +173,7 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
}
crec.start = time(NULL);
- StrnCpy(crec.machine,get_remote_machine_name(),sizeof(crec.machine)-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;
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 1a18476b75..7dd425ef8a 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -722,62 +722,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
}
/*******************************************************************
-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
-********************************************************************/
-
-static BOOL user_can_write_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.
- */
-
- if (conn->admin_user)
- return True;
-
- /* If we can't stat it does not show it */
- if (vfs_stat(conn, name, &ste) != 0)
- return False;
-
- /* Pseudo-open the file (note - no fd's created). */
-
- if(S_ISDIR(ste.st_mode))
- return True;
- else
- fsp = open_file_shared1(conn, name, &ste, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
-
- if (!fsp)
- return False;
-
- /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
- close_file(fsp, False);
-
- /* No access if SD get failed. */
- if (!sd_size)
- return False;
-
- return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA,
- &access_granted, &status);
-}
-
-/*******************************************************************
Open a directory.
********************************************************************/
@@ -837,19 +781,6 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
continue;
}
- /* Honour _hide unwriteable_ option */
- if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) {
- char *entry;
- int ret=0;
-
- if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_write_file(conn, entry);
- SAFE_FREE(entry);
- }
- if (!ret)
- continue;
- }
-
if (used + l > dirp->mallocsize) {
int s = MAX(used+l,used+2000);
char *r;
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 77d8c9cc92..dcffe3aa90 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -115,67 +115,65 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
/****************************************************************************
change a unix mode to a dos mode
****************************************************************************/
-uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
+int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
{
- int result = 0;
+ int result = 0;
- DEBUG(8,("dos_mode: %s\n", path));
+ DEBUG(8,("dos_mode: %s\n", path));
- if ((sbuf->st_mode & S_IWUSR) == 0)
- result |= aRONLY;
-
- if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
- result |= aARCH;
+ if ((sbuf->st_mode & S_IWUSR) == 0)
+ result |= aRONLY;
- 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 (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
+ result |= aARCH;
- if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) {
- result |= FILE_ATTRIBUTE_SPARSE;
- }
+ 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);
#ifdef S_ISLNK
#if LINKS_READ_ONLY
- if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
- result |= aRONLY;
+ if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
+ result |= aRONLY;
#endif
#endif
- /* hide files with a name starting with a . */
- if (lp_hide_dot_files(SNUM(conn))) {
- 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;
- }
+ /* hide files with a name starting with a . */
+ if (lp_hide_dot_files(SNUM(conn)))
+ {
+ 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 "));
+ 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 (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"));
- return(result);
+ DEBUG(8,("\n"));
+
+ return(result);
}
/*******************************************************************
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 89f05092b4..710ba396d8 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -163,7 +163,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
int write_path = -1;
if (fsp->print_file)
- return print_job_write(SNUM(fsp->conn), fsp->print_jobid, data, n);
+ return print_job_write(fsp->print_jobid, data, n);
if (!fsp->can_write) {
errno = EPERM;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index ce98af4ace..e5f9b7a0ae 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -29,6 +29,7 @@
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(char *path, char *name,connection_struct *conn,BOOL docache);
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 8bfad4ab33..996a17e932 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -443,7 +443,7 @@ 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,"B",""); /* pad */
@@ -933,7 +933,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
if (!mdrcnt && lp_disable_spoolss())
desc.errcode = ERRbuftoosmall;
- *rdata_len = desc.usedlen;
+ *rdata_len = desc.usedlen;
*rparam_len = 6;
*rparam = REALLOC(*rparam,*rparam_len);
SSVALS(*rparam,0,desc.errcode);
@@ -2181,14 +2181,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,"")))
@@ -2198,7 +2195,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;
}
@@ -2207,15 +2204,15 @@ 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;
}
@@ -2316,14 +2313,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);
@@ -2334,7 +2329,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;
}
@@ -2346,14 +2341,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;
@@ -2999,7 +2994,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;
@@ -3016,14 +3011,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) {
@@ -3554,7 +3549,7 @@ static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,cha
-const static struct
+struct
{
char *name;
int id;
diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c
index 6b53cc72aa..e2c4b43bc3 100644
--- a/source3/smbd/mangle_hash2.c
+++ b/source3/smbd/mangle_hash2.c
@@ -202,13 +202,13 @@ static BOOL is_mangled_component(const char *name)
M_DEBUG(0,("is_mangled_component %s ?\n", name));
+ /* the best distinguishing characteristic is the ~ */
+ if (name[6] != '~') return False;
+
/* check the length */
len = strlen(name);
if (len > 12 || len < 8) return False;
- /* the best distinguishing characteristic is the ~ */
- if (name[6] != '~') return False;
-
/* check extension */
if (len > 8) {
if (name[8] != '.') return False;
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 2be04fd686..81c2427a00 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -23,6 +23,7 @@
extern int Protocol;
extern int max_recv;
extern fstring global_myworkgroup;
+extern fstring remote_machine;
BOOL global_encrypted_passwords_negotiated = False;
BOOL global_spnego_negotiated = False;
struct auth_context *negprot_global_auth_context = NULL;
@@ -199,11 +200,14 @@ static int negprot_spnego(char *p)
if (lp_security() != SEC_ADS) {
blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
} else {
+ ADS_STRUCT *ads;
+ ads = ads_init_simple();
/* win2000 uses host$@REALM, which we will probably use eventually,
but for now this works */
- asprintf(&principal, "HOST/%s@%s", guid, lp_realm());
+ asprintf(&principal, "HOST/%s@%s", guid, ads->realm);
blob = spnego_gen_negTokenInit(guid, OIDs_krb5, principal);
free(principal);
+ ads_destroy(&ads);
}
memcpy(p, blob.data, blob.length);
len = blob.length;
@@ -284,12 +288,10 @@ static int reply_nt1(char *inbuf, char *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;
}
+ SSVALS(outbuf,smb_vwv16+1,8);
+ p += 8;
p += srvstr_push(outbuf, p, global_myworkgroup, -1,
STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
DEBUG(3,("not using SPNEGO\n"));
@@ -410,17 +412,8 @@ int reply_negprot(connection_struct *conn,
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++;
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index cf69dfddb0..e0a0da7a75 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -28,19 +28,19 @@ extern BOOL case_preserve;
extern BOOL short_case_preserve;
static char *known_nt_pipes[] = {
- "\\LANMAN",
- "\\srvsvc",
- "\\samr",
- "\\wkssvc",
- "\\NETLOGON",
- "\\ntlsa",
- "\\ntsvcs",
- "\\lsass",
- "\\lsarpc",
- "\\winreg",
- "\\spoolss",
- "\\netdfs",
- NULL
+ "\\LANMAN",
+ "\\srvsvc",
+ "\\samr",
+ "\\wkssvc",
+ "\\NETLOGON",
+ "\\ntlsa",
+ "\\ntsvcs",
+ "\\lsass",
+ "\\lsarpc",
+ "\\winreg",
+ "\\spoolss",
+ "\\netdfs",
+ NULL
};
/* Map generic permissions to file object specific permissions */
@@ -62,183 +62,184 @@ struct generic_mapping file_generic_mapping = {
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);
-
- 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));
+ /*
+ * Copy the param bytes into the packet.
+ */
+ if(params_sent_thistime)
+ memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
+
+ /*
+ * Copy in the data bytes
+ */
- 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);
- }
-
- /*
- * Copy the param bytes into the packet.
- */
-
- if(params_sent_thistime)
- 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);
+ 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));
+ 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.");
+ /* 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;
+ pp += params_sent_thistime;
+ pd += data_sent_thistime;
- params_to_send -= params_sent_thistime;
- data_to_send -= data_sent_thistime;
+ params_to_send -= params_sent_thistime;
+ data_to_send -= data_sent_thistime;
- /*
- * Sanity check
- */
+ /*
+ * Sanity check
+ */
- 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;
- }
- }
+ 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;
+ return 0;
}
/****************************************************************************
@@ -851,7 +852,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
p += 8;
SIVAL(p,0,fmode); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, get_allocation_size(&sbuf));
+ SOFF_T(p, 0, SMB_ROUNDUP_ALLOCATION(file_len));
p += 8;
SOFF_T(p,0,file_len);
p += 12;
@@ -1295,7 +1296,7 @@ static int call_nt_transact_create(connection_struct *conn,
p += 8;
SIVAL(p,0,fmode); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, get_allocation_size(&sbuf));
+ SOFF_T(p, 0, SMB_ROUNDUP_ALLOCATION(file_len));
p += 8;
SOFF_T(p,0,file_len);
@@ -1310,7 +1311,6 @@ static int call_nt_transact_create(connection_struct *conn,
/****************************************************************************
Reply to a NT CANCEL request.
****************************************************************************/
-
int reply_ntcancel(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -1332,7 +1332,6 @@ int reply_ntcancel(connection_struct *conn,
/****************************************************************************
Reply to an unsolicited SMBNTtranss - just ignore it!
****************************************************************************/
-
int reply_nttranss(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -1346,7 +1345,6 @@ 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,
@@ -1447,107 +1445,107 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
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;
- TALLOC_CTX *mem_ctx;
+ 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;
- files_struct *fsp = file_fsp(params,0);
+ files_struct *fsp = file_fsp(params,0);
- if(!fsp)
- return ERROR_DOS(ERRDOS,ERRbadfid);
+ if(!fsp)
+ return ERROR_DOS(ERRDOS,ERRbadfid);
- 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 = Realloc(*ppparams, 4);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
- *ppparams = params;
+ *ppparams = params;
- if ((mem_ctx = talloc_init()) == 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 = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &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 = 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);
+ }
- *ppdata = data;
+ *ppdata = data;
- memset(data, '\0', sd_size);
+ memset(data, '\0', sd_size);
- /*
- * Init the parse struct we will marshall into.
- */
+ /*
+ * Init the parse struct we will marshall into.
+ */
- prs_init(&pd, 0, mem_ctx, MARSHALL);
+ prs_init(&pd, 0, mem_ctx, MARSHALL);
- /*
- * Setup the prs_struct to point at the memory we just
- * allocated.
- */
+ /*
+ * Setup the prs_struct to point at the memory we just
+ * allocated.
+ */
- prs_give_memory( &pd, data, (uint32)sd_size, False);
+ prs_give_memory( &pd, data, (uint32)sd_size, False);
- /*
- * Finally, linearize into the outgoing buffer.
- */
+ /*
+ * 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 \
+ 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;
}
/****************************************************************************
@@ -1594,263 +1592,233 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
}
/****************************************************************************
- Reply to NT IOCTL
+ Reply to IOCTL - not implemented - no plans.
****************************************************************************/
+
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)
+ char **ppsetup, char **ppparams, char **ppdata)
{
- unsigned fnum, control;
- static BOOL logged_message;
+ static BOOL logged_message = False;
- if (setup_count != 8) {
- DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ if(!logged_message) {
+ DEBUG(3,("call_nt_transact_ioctl: Currently not implemented.\n"));
+ logged_message = True; /* Only print this once... */
}
-
- 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 */
- 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(3,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
- control));
- }
- }
-
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ return ERROR_DOS(ERRSRV,ERRnosupport);
}
/****************************************************************************
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;
+ int outsize = 0;
#if 0 /* Not used. */
- uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
- uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+ uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
+ uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
#endif /* Not used. */
- uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
- uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
- uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
- uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
- uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
- uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
- uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
- uint16 function_code = SVAL( inbuf, smb_nt_Function);
- char *params = NULL, *data = NULL, *setup = NULL;
- uint32 num_params_sofar, num_data_sofar;
- START_PROFILE(SMBnttrans);
-
- if(global_oplock_break &&
- ((function_code == NT_TRANSACT_CREATE) ||
- (function_code == NT_TRANSACT_RENAME))) {
- /*
- * Queue this open message as we are the process of an oplock break.
- */
-
- DEBUG(2,("reply_nttrans: queueing message code 0x%x \
-due to being in oplock break state.\n", (unsigned int)function_code ));
-
- push_oplock_pending_smb_message( inbuf, length);
- END_PROFILE(SMBnttrans);
- return -1;
- }
-
- if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRSRV,ERRaccess);
- }
-
- outsize = set_message(outbuf,0,0,True);
-
- /*
- * All nttrans messages we handle have smb_wct == 19 + setup_count.
- * Ensure this is so as a sanity check.
- */
-
- if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
- DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
- CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRSRV,ERRerror);
- }
+ uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
+ uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
+ uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
+ uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
+ uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
+ uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
+ uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
+ uint16 function_code = SVAL( inbuf, smb_nt_Function);
+ char *params = NULL, *data = NULL, *setup = NULL;
+ uint32 num_params_sofar, num_data_sofar;
+ START_PROFILE(SMBnttrans);
+
+ if(global_oplock_break && (function_code == NT_TRANSACT_CREATE)) {
+ /*
+ * Queue this open message as we are the process of an oplock break.
+ */
+
+ DEBUG(2,("reply_nttrans: queueing message NT_TRANSACT_CREATE \
+due to being in oplock break state.\n" ));
+
+ push_oplock_pending_smb_message( inbuf, length);
+ END_PROFILE(SMBnttrans);
+ return -1;
+ }
+
+ if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRSRV,ERRaccess);
+ }
+
+ outsize = set_message(outbuf,0,0,True);
+
+ /*
+ * All nttrans messages we handle have smb_wct == 19 + setup_count.
+ * Ensure this is so as a sanity check.
+ */
+
+ if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
+ DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
+ CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
- /* Allocate the space for the setup, the maximum needed parameters and data */
-
- if(setup_count > 0)
- setup = (char *)malloc(setup_count);
- if (total_parameter_count > 0)
- params = (char *)malloc(total_parameter_count);
- if (total_data_count > 0)
- data = (char *)malloc(total_data_count);
+ /* Allocate the space for the setup, the maximum needed parameters and data */
+
+ if(setup_count > 0)
+ setup = (char *)malloc(setup_count);
+ if (total_parameter_count > 0)
+ params = (char *)malloc(total_parameter_count);
+ if (total_data_count > 0)
+ data = (char *)malloc(total_data_count);
- if ((total_parameter_count && !params) || (total_data_count && !data) ||
- (setup_count && !setup)) {
- SAFE_FREE(setup);
- SAFE_FREE(params);
- SAFE_FREE(data);
- DEBUG(0,("reply_nttrans : Out of memory\n"));
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRDOS,ERRnomem);
- }
-
- /* Copy the param and data bytes sent with this request into the params buffer */
- num_params_sofar = parameter_count;
- num_data_sofar = data_count;
-
- if (parameter_count > total_parameter_count || data_count > total_data_count)
- exit_server("reply_nttrans: invalid sizes in packet.");
-
- if(setup) {
- memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
- DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
- dump_data(10, setup, setup_count);
- }
- if(params) {
- memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
- DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
- dump_data(10, params, parameter_count);
- }
- if(data) {
- memcpy( data, smb_base(inbuf) + data_offset, data_count);
- DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
- dump_data(10, data, data_count);
- }
-
- 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);
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_nttrans: send_smb failed.");
-
- while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
- BOOL ret;
-
- ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
-
- if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
- outsize = set_message(outbuf,0,0,True);
- if(ret) {
- DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
- } else {
- DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
- (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
- }
- SAFE_FREE(params);
- SAFE_FREE(data);
- SAFE_FREE(setup);
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRSRV,ERRerror);
- }
-
- /* Revise total_params and total_data in case they have changed downwards */
- total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
- total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
- num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
- num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
- if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
- exit_server("reply_nttrans2: data overflow in secondary nttrans packet");
-
- memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)],
- smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
- memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
- smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
- }
- }
-
- if (Protocol >= PROTOCOL_NT1)
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
-
- /* Now we must call the relevant NT_TRANS function */
- switch(function_code) {
- case NT_TRANSACT_CREATE:
- START_PROFILE_NESTED(NT_transact_create);
- 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, 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, &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, &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, &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, &params, &data);
- END_PROFILE_NESTED(NT_transact_query_security_desc);
- break;
- default:
- /* Error in request */
- DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
- SAFE_FREE(setup);
- SAFE_FREE(params);
- SAFE_FREE(data);
- END_PROFILE(SMBnttrans);
- return ERROR_DOS(ERRSRV,ERRerror);
- }
-
- /* As we do not know how many data packets will need to be
- returned here the various call_nt_transact_xxxx calls
- must send their own. Thus a call_nt_transact_xxxx routine only
- returns a value other than -1 when it wants to send
- an error packet.
- */
-
+ if ((total_parameter_count && !params) || (total_data_count && !data) ||
+ (setup_count && !setup)) {
SAFE_FREE(setup);
SAFE_FREE(params);
SAFE_FREE(data);
+ DEBUG(0,("reply_nttrans : Out of memory\n"));
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ }
+
+ /* Copy the param and data bytes sent with this request into
+ the params buffer */
+ num_params_sofar = parameter_count;
+ num_data_sofar = data_count;
+
+ if (parameter_count > total_parameter_count || data_count > total_data_count)
+ exit_server("reply_nttrans: invalid sizes in packet.");
+
+ if(setup) {
+ memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
+ DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
+ dump_data(10, setup, setup_count);
+ }
+ if(params) {
+ memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
+ DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
+ dump_data(10, params, parameter_count);
+ }
+ if(data) {
+ memcpy( data, smb_base(inbuf) + data_offset, data_count);
+ DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
+ dump_data(10, data, data_count);
+ }
+
+ 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);
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_nttrans: send_smb failed.");
+
+ while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
+ BOOL ret;
+
+ ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+ if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
+ outsize = set_message(outbuf,0,0,True);
+ if(ret) {
+ DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
+ } else {
+ DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
+ (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
+ }
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ SAFE_FREE(setup);
END_PROFILE(SMBnttrans);
- return outsize; /* If a correct response was needed the call_nt_transact_xxxx
- calls have already sent it. If outsize != -1 then it is
- returning an error packet. */
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ /* Revise total_params and total_data in case they have changed downwards */
+ total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
+ total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
+ num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
+ num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
+ if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
+ exit_server("reply_nttrans2: data overflow in secondary nttrans packet");
+
+ memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)],
+ smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
+ memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
+ smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
+ }
+ }
+
+ if (Protocol >= PROTOCOL_NT1)
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
+
+ /* Now we must call the relevant NT_TRANS function */
+ switch(function_code) {
+ case NT_TRANSACT_CREATE:
+ START_PROFILE_NESTED(NT_transact_create);
+ 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, &params, &data);
+ 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, &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, &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, &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, &params, &data);
+ END_PROFILE_NESTED(NT_transact_query_security_desc);
+ break;
+ default:
+ /* Error in request */
+ DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
+ SAFE_FREE(setup);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
+
+ /* As we do not know how many data packets will need to be
+ returned here the various call_nt_transact_xxxx calls
+ must send their own. Thus a call_nt_transact_xxxx routine only
+ returns a value other than -1 when it wants to send
+ an error packet.
+ */
+
+ SAFE_FREE(setup);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ END_PROFILE(SMBnttrans);
+ return outsize; /* If a correct response was needed the call_nt_transact_xxxx
+ calls have already sent it. If outsize != -1 then it is
+ returning an error packet. */
}
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index cfac7cf695..82c0cef77d 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -90,6 +90,29 @@ void invalidate_all_vuids(void)
}
/****************************************************************************
+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.
****************************************************************************/
@@ -184,7 +207,7 @@ 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(auth_serversupplied_info *server_info, const char *smb_name)
+int register_vuid(auth_serversupplied_info *server_info, char *smb_name)
{
user_struct *vuser = NULL;
uid_t uid;
@@ -274,7 +297,7 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
/* Create an NT_USER_TOKEN struct for this user. */
vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, vuser->guest, server_info->ptok);
- DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid));
+ DEBUG(3,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name));
next_vuid++;
num_validated_vuids++;
@@ -288,9 +311,8 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
}
/* Register a home dir service for this user */
- if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) {
- DEBUG(3, ("Adding/updating homes service for user '%s' using home direcotry: '%s'\n",
- vuser->user.unix_name, vuser->unix_homedir));
+ if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)
+ && (lp_servicenumber(vuser->user.unix_name) < 0)) {
vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir);
} else {
vuser->homes_snum = -1;
@@ -303,7 +325,7 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
/****************************************************************************
add a name to the session users list
****************************************************************************/
-void add_session_user(const char *user)
+void add_session_user(char *user)
{
fstring suser;
StrnCpy(suser,user,sizeof(suser)-1);
@@ -351,7 +373,7 @@ BOOL user_ok(const char *user,int snum)
if (valid) str_list_free (&valid);
if (ret && lp_onlyuser(snum)) {
- char **user_list = str_list_make (lp_username(snum), NULL);
+ char **user_list = str_list_make (lp_username(snum));
if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) {
ret = user_in_list(user, user_list);
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 043e33e836..85818d524a 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2296,7 +2296,7 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
switch(tagtype) {
case SMB_ACL_USER_OBJ:
perms = unix_perms_to_acl_perms(mode, S_IRUSR, S_IWUSR, S_IXUSR);
- break;
+ break;
case SMB_ACL_GROUP_OBJ:
perms = unix_perms_to_acl_perms(mode, S_IRGRP, S_IWGRP, S_IXGRP);
break;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 55234ec896..43d3c6c531 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -152,7 +152,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)
@@ -341,9 +341,9 @@ force write permissions on print services.
functions. Any message that has a NULL function is unimplemented -
please feel free to contribute implementations!
*/
-const static struct smb_message_struct
+static struct smb_message_struct
{
- const char *name;
+ char *name;
int (*fn)(connection_struct *conn, char *, char *, int, int);
int flags;
}
@@ -386,7 +386,7 @@ const static 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},
@@ -399,7 +399,7 @@ const static struct smb_message_struct
/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
/* 0x30 */ { NULL, NULL, 0 },
/* 0x31 */ { NULL, NULL, 0 },
-/* 0x32 */ { "SMBtrans2", reply_trans2, AS_USER | CAN_IPC },
+/* 0x32 */ { "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK | CAN_IPC },
/* 0x33 */ { "SMBtranss2", reply_transs2, AS_USER},
/* 0x34 */ { "SMBfindclose", reply_findclose,AS_USER},
/* 0x35 */ { "SMBfindnclose", reply_findnclose, AS_USER},
@@ -611,7 +611,7 @@ const static struct smb_message_struct
/*******************************************************************
dump a prs to a file
********************************************************************/
-static void smb_dump(const char *name, int type, char *data, ssize_t len)
+static void smb_dump(char *name, int type, char *data, ssize_t len)
{
int fd, i;
pstring fname;
@@ -896,7 +896,7 @@ void process_smb(char *inbuf, char *outbuf)
/****************************************************************************
return a string containing the function name of a SMB command
****************************************************************************/
-const char *smb_fn_name(int type)
+char *smb_fn_name(int type)
{
static char *unknown_name = "SMBunknown";
@@ -1228,6 +1228,13 @@ void smbd_process(void)
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);
+ talloc_init_named("dummy!");
+
while (True) {
int deadtime = lp_deadtime()*60;
int select_timeout = setup_select_timeout();
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index c6a082d7d8..0ccdf7c241 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -38,6 +38,7 @@ extern pstring global_myname;
extern int global_oplock_break;
unsigned int smb_echo_count = 0;
+extern fstring remote_machine;
extern BOOL global_encrypted_passwords_negotiated;
@@ -52,11 +53,10 @@ int reply_special(char *inbuf,char *outbuf)
int msg_flags = CVAL(inbuf,1);
pstring name1,name2;
+ extern fstring local_machine;
int len;
char name_type = 0;
- static BOOL already_got_session = False;
-
*name1 = *name2 = 0;
memset(outbuf,'\0',smb_size);
@@ -65,11 +65,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 ||
@@ -82,19 +77,24 @@ int reply_special(char *inbuf,char *outbuf)
DEBUG(2,("netbios connect: name1=%s name2=%s\n",
name1,name2));
- name1[15] = 0;
+ 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);
- len = strlen(name2);
+ fstrcpy(local_machine,name1);
+ len = strlen(local_machine);
if (len == 16) {
- name_type = name2[15];
- name2[15] = 0;
+ name_type = local_machine[15];
+ local_machine[15] = 0;
}
-
- set_local_machine_name(name1);
- set_remote_machine_name(name2);
+ 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\n",
- get_local_machine_name(), get_remote_machine_name() ));
+ local_machine, remote_machine ));
if (name_type == 'R') {
/* We are being asked for a pathworks session ---
@@ -107,7 +107,7 @@ int reply_special(char *inbuf,char *outbuf)
of possibly valid usernames if we are operating
in share mode security */
if (lp_security() == SEC_SHARE) {
- add_session_user(get_remote_machine_name());
+ add_session_user(remote_machine);
}
reload_services(True);
@@ -115,7 +115,6 @@ int reply_special(char *inbuf,char *outbuf)
claim_connection(NULL,"",MAXSTATUS,True);
- already_got_session = True;
break;
case 0x89: /* session keepalive request
@@ -149,8 +148,7 @@ 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;
+ pstring service;
pstring password;
pstring dev;
int outsize = 0;
@@ -162,19 +160,17 @@ int reply_tcon(connection_struct *conn,
START_PROFILE(SMBtcon);
- *service_buf = *password = *dev = 0;
+ *service = *password = *dev = 0;
p = smb_buf(inbuf)+1;
- p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service), STR_TERMINATE) + 1;
+ p += srvstr_pull_buf(inbuf, service, p, sizeof(service), 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;
- p = strrchr_m(service_buf,'\\');
+ p = strrchr_m(service,'\\');
if (p) {
- service = p+1;
- } else {
- service = service_buf;
+ pstrcpy(service, p+1);
}
password_blob = data_blob(password, pwlen+1);
@@ -358,13 +354,10 @@ int reply_ioctl(connection_struct *conn,
switch (ioctl_code)
{
case IOCTL_QUERY_JOB_INFO:
- {
- uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid);
- SSVAL(p,0,rap_jobid); /* Job number */
+ SSVAL(p,0,fsp->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;
- }
}
END_PROFILE(SMBioctl);
@@ -2751,8 +2744,6 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
srvstr_pull_buf(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE);
- RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
-
status = mkdir_internal(conn, directory);
if (!NT_STATUS_IS_OK(status))
return ERROR_NT(status);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index b2b905cec3..6f0d0238b0 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -38,6 +38,8 @@ extern pstring user_socket_options;
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 :(
@@ -131,7 +133,7 @@ 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);
@@ -149,15 +151,13 @@ static void msg_exit_server(int msg_type, pid_t src, void *buf, size_t len)
Open the socket communication.
****************************************************************************/
-static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
+static BOOL open_sockets(BOOL is_daemon,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();
@@ -176,106 +176,73 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
/* 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_PORTS;
- }
- ports = strdup(ports);
- } else {
- ports = strdup(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;
- 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);
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
- if (listen(s, 5) == -1) {
- DEBUG(0,("listen: %s\n",strerror(errno)));
- close(s);
- return False;
- }
- 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;
- }
+ 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;
- 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);
-
- if (listen(s, 5) == -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);
@@ -326,7 +293,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
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
@@ -342,7 +309,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
continue;
if (smbd_server_fd() == -1) {
- DEBUG(0,("open_sockets_smbd: accept: %s\n",
+ DEBUG(0,("open_sockets: accept: %s\n",
strerror(errno)));
continue;
}
@@ -351,21 +318,17 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
/* 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_socket_addr(smbd_server_fd()));
-
/* Reset global variables in util.c so
that client substitutions will be
done correctly in the process. */
@@ -419,6 +382,8 @@ BOOL reload_services(BOOL test)
{
BOOL ret;
+ set_register_printer_fn();
+
if (lp_loaded()) {
pstring fname;
pstrcpy(fname,lp_configfile());
@@ -646,7 +611,7 @@ static void usage(char *pname)
BOOL is_daemon = False;
BOOL interactive = False;
BOOL specified_logfile = False;
- char *ports = NULL;
+ int port = SMB_PORT;
int opt;
pstring logfile;
@@ -701,7 +666,7 @@ static void usage(char *pname)
break;
case 'p':
- ports = optarg;
+ port = atoi(optarg);
break;
case 'h':
@@ -740,7 +705,7 @@ static void usage(char *pname)
lp_set_logfile(logfile);
}
- set_remote_machine_name("smbd");
+ fstrcpy(remote_machine, "smbd");
setup_logging(argv[0],interactive);
@@ -808,6 +773,11 @@ static void usage(char *pname)
init_structs();
+ /* don't call winbind for our domain if we are the DC */
+ if (lp_domain_logons()) {
+ winbind_exclude_domain(lp_workgroup());
+ }
+
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
DEBUG(0,("ERROR: failed to setup profiling\n"));
@@ -869,15 +839,13 @@ static void usage(char *pname)
start_background_queue();
*/
- if (!open_sockets_smbd(is_daemon,ports))
+ if (!open_sockets(is_daemon,port))
exit(1);
/*
* everything after this point is run after the fork()
*/
- namecache_enable();
-
if (!locking_init(0))
exit(1);
@@ -921,13 +889,6 @@ static void usage(char *pname)
if (!init_change_notify())
exit(1);
- /* re-initialise the timezone */
- TimeInit();
-
- /* register our message handlers */
- message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis);
- talloc_init_named("dummy!");
-
smbd_process();
uni_group_cache_shutdown();
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 6f83a2d3b7..9ac610ab5a 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -27,7 +27,9 @@ 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;
/****************************************************************************
@@ -102,9 +104,7 @@ int add_home_service(const char *service, const char *username, const char *home
}
}
- if (!lp_add_home(service, iHomeService, username, homedir)) {
- return -1;
- }
+ lp_add_home(service, iHomeService, username, homedir);
return lp_servicenumber(service);
@@ -347,7 +347,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
}
if (lp_guest_only(snum)) {
- const char *guestname = lp_guestaccount();
+ char *guestname = lp_guestaccount();
guest = True;
force = True;
pass = getpwnam_alloc(guestname);
@@ -521,7 +521,7 @@ 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));
}
/* groups stuff added by ih */
@@ -634,7 +634,7 @@ 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)));
@@ -645,7 +645,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
#else
/* the alternative is just to check the directory exists */
if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
- DEBUG(0,("'%s' 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);
@@ -674,7 +674,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
*/
if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
- dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address );
+ dbgtext( "%s (%s) ", remote_machine, conn->client_address );
dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
dbgtext( "initially as user %s ", user );
dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
@@ -759,7 +759,6 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
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;
}
}
@@ -774,15 +773,12 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
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 becouse it was not found or created at session setup time\n"));
- *status = NT_STATUS_BAD_NETWORK_NAME;
- return NULL;
+ if (vuser->homes_snum != -1) {
+ 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);
}
- 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. */
@@ -801,7 +797,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
}
}
} else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
- && strequal(service_in, lp_servicename(vuser->homes_snum))) {
+ && strequal(service, 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));
return make_connection_snum(vuser->homes_snum,
@@ -823,7 +819,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
}
DEBUG(0,("%s (%s) couldn't find service %s\n",
- get_remote_machine_name(), client_addr(), service));
+ remote_machine, client_addr(), service));
*status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
}
@@ -845,7 +841,7 @@ 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))));
if (conn->vfs_ops.disconnect != NULL) {
diff --git a/source3/smbd/session.c b/source3/smbd/session.c
index 54b7a24b07..dade953ec1 100644
--- a/source3/smbd/session.c
+++ b/source3/smbd/session.c
@@ -27,22 +27,21 @@
#include "includes.h"
+extern fstring remote_machine;
+
static TDB_CONTEXT *tdb;
/* called when a session is created */
BOOL session_claim(user_struct *vuser)
{
- int i = 0;
+ int i;
TDB_DATA data;
struct sessionid sessionid;
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 */
@@ -64,37 +63,18 @@ BOOL session_claim(user_struct *vuser)
data.dptr = NULL;
data.dsize = 0;
-#if WITH_UTMP
- 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
-#endif
- {
- 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 (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;
}
/* If 'hostname lookup' == yes, then do the DNS lookup. This is
@@ -110,25 +90,24 @@ BOOL session_claim(user_struct *vuser)
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.remote_machine, remote_machine);
fstrcpy(sessionid.ip_addr, client_addr());
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) {
+ if (tdb_store(tdb, key, data, TDB_MODIFY) != 0) {
DEBUG(1,("session_claim: unable to create session id record\n"));
return False;
}
@@ -140,11 +119,7 @@ BOOL session_claim(user_struct *vuser)
}
#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;
}
@@ -154,15 +129,18 @@ void session_yield(user_struct *vuser)
TDB_DATA dbuf;
struct sessionid sessionid;
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);
+
+ key.dptr = keystr;
+ key.dsize = strlen(keystr)+1;
dbuf = tdb_fetch(tdb, key);
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 8fb5a50697..867b00ff5c 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -3,7 +3,6 @@
handle SMBsessionsetup
Copyright (C) Andrew Tridgell 1998-2001
Copyright (C) Andrew Bartlett 2001
- Copyright (C) Jim McDonough 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
@@ -123,12 +122,6 @@ static int reply_spnego_kerberos(connection_struct *conn,
ads = ads_init_simple();
- if (!ads) {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- ads->auth.realm = strdup(lp_realm());
-
ret = ads_verify_ticket(ads, &ticket, &client, &auth_data);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(1,("Failed to verify incoming ticket!\n"));
@@ -146,7 +139,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
}
*p = 0;
- if (strcasecmp(p+1, ads->auth.realm) != 0) {
+ if (strcasecmp(p+1, ads->realm) != 0) {
DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
if (!lp_allow_trusted_domains()) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
@@ -207,7 +200,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
send a security blob via a session setup reply
****************************************************************************/
static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
- DATA_BLOB blob, uint32 errcode)
+ DATA_BLOB blob)
{
char *p;
@@ -216,7 +209,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
/* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end
that we aren't finished yet */
- SIVAL(outbuf, smb_rcls, errcode);
+ SIVAL(outbuf, smb_rcls, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED));
SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
SSVAL(outbuf, smb_vwv3, blob.length);
p = smb_buf(outbuf);
@@ -243,12 +236,11 @@ static int reply_spnego_negotiate(connection_struct *conn,
DATA_BLOB secblob;
int i;
uint32 ntlmssp_command, neg_flags, chal_flags;
- DATA_BLOB chal, spnego_chal;
+ DATA_BLOB chal, spnego_chal, extra_data;
const uint8 *cryptkey;
BOOL got_kerberos = False;
NTSTATUS nt_status;
extern pstring global_myname;
- char *cliname=NULL, *domname=NULL;
/* parse out the OIDs and the first sec blob */
if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
@@ -266,7 +258,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
DEBUG(3,("Got secblob of size %d\n", secblob.length));
#ifdef HAVE_KRB5
- if (got_kerberos && (SEC_ADS == lp_security())) {
+ if (got_kerberos) {
int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
length, bufsize, &secblob);
data_blob_free(&secblob);
@@ -279,16 +271,19 @@ static int reply_spnego_negotiate(connection_struct *conn,
file_save("secblob.dat", secblob.data, secblob.length);
#endif
- if (!msrpc_parse(&secblob, "CddAA",
+ if (!msrpc_parse(&secblob, "CddB",
"NTLMSSP",
&ntlmssp_command,
&neg_flags,
- &cliname,
- &domname)) {
+ &extra_data)) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
+ DEBUG(5, ("Extra data: \n"));
+ dump_data(5, extra_data.data, extra_data.length);
+
data_blob_free(&secblob);
+ data_blob_free(&extra_data);
if (ntlmssp_command != NTLMSSP_NEGOTIATE) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
@@ -317,39 +312,36 @@ static int reply_spnego_negotiate(connection_struct *conn,
NTLMSSP_CHAL_TARGET_INFO;
{
- DATA_BLOB domain_blob, struct_blob;
- fstring dnsname, dnsdomname;
+ DATA_BLOB domain_blob, netbios_blob, realm_blob;
msrpc_gen(&domain_blob,
"U",
lp_workgroup());
- fstrcpy(dnsdomname, lp_realm());
- strlower(dnsdomname);
-
- fstrcpy(dnsname, global_myname);
- fstrcat(dnsname, ".");
- fstrcat(dnsname, lp_realm());
- strlower(dnsname);
-
- msrpc_gen(&struct_blob, "aaaaa",
- 2, lp_workgroup(),
- 1, global_myname,
- 4, dnsdomname,
- 3, dnsname,
- 0, "");
+ msrpc_gen(&netbios_blob,
+ "U",
+ global_myname);
+
+ msrpc_gen(&realm_blob,
+ "U",
+ lp_realm());
+
- msrpc_gen(&chal, "CdUdbddB",
+ msrpc_gen(&chal, "CddddbBBBB",
"NTLMSSP",
NTLMSSP_CHALLENGE,
- lp_workgroup(),
+ 0,
+ 0x30, /* ?? */
chal_flags,
cryptkey, 8,
- 0, 0,
- struct_blob.data, struct_blob.length);
+ domain_blob.data, domain_blob.length,
+ domain_blob.data, domain_blob.length,
+ netbios_blob.data, netbios_blob.length,
+ realm_blob.data, realm_blob.length);
data_blob_free(&domain_blob);
- data_blob_free(&struct_blob);
+ data_blob_free(&netbios_blob);
+ data_blob_free(&realm_blob);
}
if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) {
@@ -359,7 +351,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
}
/* now tell the client to send the auth packet */
- reply_sesssetup_blob(conn, outbuf, spnego_chal, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED));
+ reply_sesssetup_blob(conn, outbuf, spnego_chal);
data_blob_free(&chal);
data_blob_free(&spnego_chal);
@@ -376,7 +368,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
int length, int bufsize,
DATA_BLOB blob1)
{
- DATA_BLOB auth, response;
+ DATA_BLOB auth;
char *workgroup = NULL, *user = NULL, *machine = NULL;
DATA_BLOB lmhash, nthash, sess_key;
DATA_BLOB plaintext_password = data_blob(NULL, 0);
@@ -421,13 +413,6 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n",
user, workgroup, machine, lmhash.length, nthash.length));
- /* 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(machine);
-
- reload_services(True);
-
#if 0
file_save("nthash1.dat", nthash.data, nthash.length);
file_save("lmhash1.dat", lmhash.data, lmhash.length);
@@ -496,12 +481,8 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
-
- response = spnego_gen_auth_response();
- reply_sesssetup_blob(conn, outbuf, response, 0);
-
- /* and tell smbd that we have already replied to this packet */
- return -1;
+
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -613,6 +594,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
extern BOOL global_encrypted_passwords_negotiated;
extern BOOL global_spnego_negotiated;
extern int Protocol;
+ extern fstring remote_machine;
extern userdom_struct current_user_info;
extern int max_send;
@@ -648,8 +630,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
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 (passlen1 > MAX_PASS_LEN) {
+ return ERROR_DOS(ERRDOS,ERRbuftoosmall);
}
if (doencrypt) {
@@ -683,6 +665,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
}
}
+ if (passlen1 > MAX_PASS_LEN) {
+ 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.
@@ -700,29 +689,19 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
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;
- srvstr_pull(inbuf, pass, smb_buf(inbuf),
- sizeof(pass), passlen1, STR_TERMINATE);
- plaintext_password = data_blob(pass, strlen(pass)+1);
+ plaintext_password = data_blob(p, passlen1+1);
+ /* Ensure null termination */
+ plaintext_password.data[passlen1] = 0;
}
p += passlen1 + passlen2;
@@ -741,7 +720,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
- DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name()));
+ DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
if (*user) {
if (global_spnego_negotiated) {
diff --git a/source3/smbd/ssl.c b/source3/smbd/ssl.c
new file mode 100644
index 0000000000..7fcb48a954
--- /dev/null
+++ b/source3/smbd/ssl.c
@@ -0,0 +1,286 @@
+/*
+ Unix SMB/CIFS implementation.
+ 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/source3/smbd/trans2.c b/source3/smbd/trans2.c
index a66c029286..f1dfb39aac 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -30,19 +30,6 @@ extern int global_oplock_break;
extern uint32 global_client_caps;
extern pstring global_myname;
-/* given a stat buffer return the allocated size on disk, taking into
- account sparse files */
-SMB_OFF_T get_allocation_size(SMB_STRUCT_STAT *sbuf)
-{
- SMB_OFF_T ret;
- ret = sbuf->st_blksize * (SMB_OFF_T)sbuf->st_blocks;
- ret = SMB_ROUNDUP_ALLOCATION(ret);
- return ret;
-}
-
-#define get_file_size(sbuf) (sbuf.st_size)
-
-
/****************************************************************************
Send the required number of replies back.
We assume all fields other than the data fields are
@@ -269,7 +256,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- size = get_file_size(sbuf);
+ size = sbuf.st_size;
fmode = dos_mode(conn,fname,&sbuf);
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
@@ -466,7 +453,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
uint32 reskey=0;
int prev_dirpos=0;
int mode=0;
- SMB_OFF_T file_size = 0;
+ SMB_OFF_T size = 0;
SMB_OFF_T allocation_size = 0;
uint32 len;
time_t mdate=0, adate=0, cdate=0;
@@ -578,8 +565,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
continue;
}
- file_size = get_file_size(sbuf);
- allocation_size = get_allocation_size(&sbuf);
+ size = sbuf.st_size;
+ allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
mdate = sbuf.st_mtime;
adate = sbuf.st_atime;
cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
@@ -591,7 +578,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));
@@ -615,7 +602,7 @@ 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;
@@ -634,7 +621,7 @@ 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);
SIVAL(p,l2_cbList,0); /* No extended attributes */
@@ -654,7 +641,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
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);
+ SOFF_T(p,0,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@@ -688,7 +675,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
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);
+ SOFF_T(p,0,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@@ -709,7 +696,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
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);
+ SOFF_T(p,0,size);
SOFF_T(p,8,allocation_size);
p += 16;
SIVAL(p,0,nt_extmode); p += 4;
@@ -748,14 +735,14 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
/* Begin of SMB_QUERY_FILE_UNIX_BASIC */
- SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
+ SOFF_T(p,0,sbuf.st_size); /* File size 64 Bit */
p+= 8;
#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
SOFF_T(p,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
#else
/* Can't get the value - fake it using size. */
- SOFF_T(p,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
+ SOFF_T(p,0,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
#endif
p+= 8;
@@ -1541,7 +1528,7 @@ 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_OFF_T size=0;
SMB_OFF_T allocation_size=0;
unsigned int data_size;
SMB_STRUCT_STAT sbuf;
@@ -1656,10 +1643,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
mode = dos_mode(conn,fname,&sbuf);
fullpathname = fname;
- file_size = get_file_size(sbuf);
- allocation_size = get_allocation_size(&sbuf);
+ size = sbuf.st_size;
+ allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
if (mode & aDIR)
- file_size = 0;
+ size = 0;
params = Realloc(*pparams,2);
if (params == NULL)
@@ -1705,7 +1692,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
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_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 */
@@ -1716,7 +1703,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
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,12,(uint32)size);
SIVAL(pdata,16,(uint32)allocation_size);
SIVAL(pdata,20,mode);
break;
@@ -1760,8 +1747,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_QUERY_FILE_STANDARD_INFO:
data_size = 24;
+ /* Fake up allocation size. */
SOFF_T(pdata,0,allocation_size);
- SOFF_T(pdata,8,file_size);
+ SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink);
SCVAL(pdata,20,0);
SCVAL(pdata,21,(mode&aDIR)?1:0);
@@ -1806,7 +1794,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_QUERY_FILE_END_OF_FILEINFO:
data_size = 8;
- SOFF_T(pdata,0,file_size);
+ SOFF_T(pdata,0,size);
break;
case SMB_QUERY_FILE_ALL_INFO:
@@ -1817,7 +1805,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,32,mode);
pdata += 40;
SOFF_T(pdata,0,allocation_size);
- SOFF_T(pdata,8,file_size);
+ SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink);
SCVAL(pdata,20,delete_pending);
SCVAL(pdata,21,(mode&aDIR)?1:0);
@@ -1929,7 +1917,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
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);
+ SOFF_T(pdata,8,size);
SIVAL(pdata,16,allocation_size);
SIVAL(pdata,20,0); /* ??? */
data_size = 24 + byte_len;
@@ -1937,7 +1925,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
case SMB_FILE_COMPRESSION_INFORMATION:
- SOFF_T(pdata,0,allocation_size);
+ SOFF_T(pdata,0,size);
SIVAL(pdata,8,0); /* ??? */
SIVAL(pdata,12,0); /* ??? */
data_size = 16;
@@ -1949,7 +1937,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
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);
+ SOFF_T(pdata,40,size);
SIVAL(pdata,48,mode);
SIVAL(pdata,52,0); /* ??? */
data_size = 56;
@@ -1969,14 +1957,14 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
- SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
+ SOFF_T(pdata,0,sbuf.st_size); /* File size 64 Bit */
pdata += 8;
#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
SOFF_T(pdata,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
#else
/* Can't get the value - fake it using size. */
- SOFF_T(pdata,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
+ SOFF_T(pdata,0,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
#endif
pdata += 8;
@@ -2258,8 +2246,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
- } else
- return (UNIXERROR(ERRDOS,ERRbadpath));
+ }
} else {
/*
* Original code - this is an open file.
@@ -2323,7 +2310,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
sbuf.st_mtime = fsp->pending_modtime;
}
- size = get_file_size(sbuf);
+ size = sbuf.st_size;
tvs.modtime = sbuf.st_mtime;
tvs.actime = sbuf.st_atime;
dosmode = dos_mode(conn,fname,&sbuf);
@@ -2426,7 +2413,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
fname, (double)allocation_size ));
- if(allocation_size != get_file_size(sbuf)) {
+ if(allocation_size != sbuf.st_size) {
SMB_STRUCT_STAT new_sbuf;
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
@@ -2472,8 +2459,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (ret == -1)
return ERROR_NT(NT_STATUS_DISK_FULL);
- /* Allocate can truncate size... */
- size = get_file_size(new_sbuf);
+ /* Allocate can trucate size... */
+ size = new_sbuf.st_size;
}
break;
@@ -2728,7 +2715,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* changing the size of a file.
*/
if (!size)
- size = get_file_size(sbuf);
+ size = sbuf.st_size;
}
/*
@@ -2770,7 +2757,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
}
- if (size != get_file_size(sbuf)) {
+ if(size != sbuf.st_size) {
int ret;
@@ -2983,11 +2970,9 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
{
char *pdata = *ppdata;
files_struct *fsp = file_fsp(inbuf,smb_vwv15);
-
+
if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
- uint16 rap_jobid;
-
pdata = Realloc(*ppdata, 32);
if(pdata == NULL)
return ERROR_DOS(ERRDOS,ERRnomem);
@@ -2996,8 +2981,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
/* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
CAN ACCEPT THIS IN UNICODE. JRA. */
- rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); /* Job number */
- SSVAL(pdata,0,rap_jobid); /* Job number */
+ SSVAL(pdata,0,fsp->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 */
send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index c0bacf8f91..a18f62c9cc 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -440,43 +440,44 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N
extern pstring global_myname;
extern fstring global_myworkgroup;
fstring sid;
- BOOL local_lookup = False;
+ BOOL ret = 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(global_myname, domain)) {
- local_lookup = True;
- } else if (lp_server_role() == ROLE_DOMAIN_PDC ||
- lp_server_role() == ROLE_DOMAIN_PDC) {
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
if (strequal(domain, global_myworkgroup)) {
- local_lookup = True;
+ ret = local_lookup_name(name, psid, name_type);
}
- }
-
- if (local_lookup) {
- 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;
+ /* No break is deliberate here. JRA. */
+ default:
+ if (ret) {
+ } else if (strequal(global_myname, domain)) {
+ ret = local_lookup_name(name, psid, name_type);
+ } else {
+ DEBUG(5, ("lookup_name: domain %s is not local\n", domain));
}
}
- DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n",
- local_lookup ? "local" : "winbind", domain, name));
+ if (ret) {
+ 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 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: winbind and local lookups for [%s]\\[%s] failed\n", domain, name));
return False;
}
@@ -592,17 +593,13 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
was done correctly, False if not. sidtype is set by this function.
*****************************************************************/
-BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
+BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
{
fstring sid_str;
/* if we know its local then don't try winbindd */
if (sid_compare_domain(get_global_sam_sid(), psid) == 0) {
- BOOL result;
- become_root();
- result = local_sid_to_uid(puid, psid, sidtype);
- unbecome_root();
- return result;
+ return local_sid_to_uid(puid, psid, sidtype);
}
/* (tridge) I commented out the slab of code below in order to support foreign SIDs
@@ -668,7 +665,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
was done correctly, False if not.
*****************************************************************/
-BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
+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;
@@ -679,21 +676,16 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
* First we must look up the name and decide if this is a group sid.
*/
- /* if we know its local then don't try winbindd */
- if (sid_compare_domain(get_global_sam_sid(), psid) == 0) {
- BOOL result;
- become_root();
- result = local_sid_to_gid(pgid, psid, sidtype);
- unbecome_root();
- return result;
- }
-
if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
- DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n",
+ DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
sid_to_string(sid_str, psid) ));
- /* this was probably a foreign sid - assume its a group rid
- and continue */
- name_type = SID_NAME_DOM_GRP;
+ if (!local_sid_to_gid(pgid, psid, sidtype)) {
+ /* this was probably a foreign sid - assume its a group rid
+ and continue */
+ name_type = SID_NAME_DOM_GRP;
+ } else {
+ return True;
+ }
}
/*
@@ -704,7 +696,7 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
(unsigned int)name_type ));
- return False;
+ return local_sid_to_gid(pgid, psid, sidtype);
}
*sidtype = name_type;
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index a2291eba08..5e1dc68bdb 100644
--- a/source3/smbd/vfs.c
+++ b/source3/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,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.
*/
#include "includes.h"
@@ -31,12 +28,6 @@ struct vfs_syminfo {
void *fptr;
};
-/*
- Opaque (final) vfs operations. This is a combination of first-met opaque vfs operations
- across all currently processed modules. */
-
-static vfs_op_tuple vfs_opaque_ops[SMB_VFS_OP_LAST];
-
/* Default vfs hooks. WARNING: The order of these initialisers is
very important. They must be in the same order as defined in
vfs.h. Change at your own peril. */
@@ -126,75 +117,58 @@ static struct vfs_ops default_vfs_ops = {
initialise default vfs hooks
****************************************************************************/
-static void vfs_init_default(connection_struct *conn)
+static BOOL vfs_init_default(connection_struct *conn)
{
DEBUG(3, ("Initialising default vfs hooks\n"));
memcpy(&conn->vfs_ops, &default_vfs_ops, sizeof(struct vfs_ops));
- conn->vfs_private = NULL;
+ return True;
}
/****************************************************************************
initialise custom vfs hooks
****************************************************************************/
-static BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
+static BOOL vfs_init_custom(connection_struct *conn)
{
int vfs_version = -1;
- vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *);
- int i;
+ struct vfs_ops *ops, *(*init_fptr)(int *, struct vfs_ops *);
- DEBUG(3, ("Initialising custom vfs hooks from %s\n", vfs_object));
+ DEBUG(3, ("Initialising custom vfs hooks from %s\n", lp_vfsobj(SNUM(conn))));
/* Open object file */
- if ((conn->vfs_private->handle = sys_dlopen(vfs_object, RTLD_NOW)) == NULL) {
- DEBUG(0, ("Error opening %s: %s\n", vfs_object, sys_dlerror()));
+ 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;
}
/* Get handle on vfs_init() symbol */
- init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init");
+ init_fptr = (struct vfs_ops *(*)(int *, struct vfs_ops *))sys_dlsym(conn->dl_handle, "vfs_init");
if (init_fptr == NULL) {
- DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object));
+ DEBUG(0, ("No vfs_init() symbol found in %s\n", lp_vfsobj(SNUM(conn))));
return False;
}
/* Initialise vfs_ops structure */
- if ((ops = init_fptr(&vfs_version, &conn->vfs_ops, conn->vfs_private)) == NULL) {
- DEBUG(0, ("vfs_init() function from %s failed\n", vfs_object));
- return False;
- }
-
- if ((vfs_version < SMB_VFS_INTERFACE_CASCADED)) {
- DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n",
- vfs_version, SMB_VFS_INTERFACE_VERSION ));
- return False;
- }
-
- if ((vfs_version < SMB_VFS_INTERFACE_VERSION)) {
- DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\
-Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n",
- vfs_version, SMB_VFS_INTERFACE_VERSION, vfs_version ));
- return False;
- }
-
- for(i=0; ops[i].op != NULL; i++) {
- DEBUG(3, ("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(vfs_opaque_ops[ops[i].type].op == ((void**)&default_vfs_ops)[ops[i].type]) {
- /* No, it isn't overloaded yet. Overload. */
- DEBUG(3, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
- vfs_opaque_ops[ops[i].type] = ops[i];
- }
- }
- /* Change current VFS disposition*/
- DEBUG(3, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object));
- ((void**)&conn->vfs_ops)[ops[i].type] = ops[i].op;
+ 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;
+ }
+
+ 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;
+ }
+
+ if (ops != &conn->vfs_ops) {
+ memcpy(&conn->vfs_ops, ops, sizeof(struct vfs_ops));
}
return True;
@@ -206,70 +180,21 @@ Proceeding in compatibility mode, new operations (since version #%d) will fallba
BOOL smbd_vfs_init(connection_struct *conn)
{
- char **vfs_objects, *vfsobj, *vfs_module, *vfs_path;
- int nobj, i;
- struct smb_vfs_handle_struct *handle;
-
- /* Normal share - initialise with disk access functions */
- vfs_init_default(conn);
-
- /* Override VFS functions if 'vfs object' was specified*/
if (*lp_vfsobj(SNUM(conn))) {
- vfsobj = NULL;
- for(i=0; i<SMB_VFS_OP_LAST; i++) {
- vfs_opaque_ops[i].op = ((void**)&default_vfs_ops)[i];
- vfs_opaque_ops[i].type = i;
- vfs_opaque_ops[i].layer = SMB_VFS_LAYER_OPAQUE;
+
+ /* Loadable object file */
+
+ if (!vfs_init_custom(conn)) {
+ DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed\n"));
+ return False;
}
- if (string_set(&vfsobj, lp_vfsobj(SNUM(conn)))) {
- /* Parse passed modules specification to array of modules */
- set_first_token(vfsobj);
- /* We are using default separators: ' \t\r\n' */
- vfs_objects = toktocliplist(&nobj, NULL);
- if (vfs_objects) {
- vfs_path = lp_vfs_path(SNUM(conn));
- conn->vfs_private = NULL;
- for(i=nobj-1; i>=0; i--) {
- handle = (struct smb_vfs_handle_struct *) smb_xmalloc(sizeof(smb_vfs_handle_struct));
- /* Loadable object file */
- handle->handle = NULL;
- DLIST_ADD(conn->vfs_private, handle)
- vfs_module = NULL;
- if (vfs_path) {
- asprintf(&vfs_module, "%s/%s", vfs_path, vfs_objects[i]);
- } else {
- asprintf(&vfs_module, "%s", vfs_objects[i]);
- }
- if (!vfs_init_custom(conn, vfs_module)) {
- DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_module));
- string_free(&vfsobj);
- SAFE_FREE(vfs_module);
- return False;
- }
- SAFE_FREE(vfs_module);
- }
- }
- string_free(&vfsobj);
- return True;
- }
- }
- return True;
-}
-
-/*******************************************************************
- Create vfs_ops reflecting current vfs_opaque_ops
-*******************************************************************/
-struct vfs_ops *smb_vfs_get_opaque_ops(void)
-{
- int i;
- struct vfs_ops *ops;
- ops = smb_xmalloc(sizeof(struct vfs_ops));
-
- for(i=0; i<SMB_VFS_OP_LAST; i++) {
- ((void**)ops)[i] = vfs_opaque_ops[i].op;
- }
- return ops;
+ return True;
+ }
+
+ /* Normal share - initialise with disk access functions */
+
+ return vfs_init_default(conn);
}
/*******************************************************************
diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c
index a62f7af1ad..c34b4c1ad2 100644
--- a/source3/torture/locktest.c
+++ b/source3/torture/locktest.c
@@ -136,7 +136,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, int snum)
{
struct cli_state *c;
struct nmb_name called, calling;
diff --git a/source3/torture/locktest2.c b/source3/torture/locktest2.c
index 58817bbd36..3c24cfaa4a 100644
--- a/source3/torture/locktest2.c
+++ b/source3/torture/locktest2.c
@@ -149,14 +149,15 @@ 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,'\\');
@@ -166,6 +167,40 @@ static struct cli_state *connect_one(char *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_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) {
@@ -173,16 +208,37 @@ static struct cli_state *connect_one(char *share)
}
}
- slprintf(myname,sizeof(myname), "lock-%u-%u", 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);
+ /*
+ * 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;
diff --git a/source3/utils/net.c b/source3/utils/net.c
index fc7094bcf7..d34ac21f39 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -234,7 +234,7 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
}
-BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
+BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, char *domain_name)
{
struct in_addr *ip_list;
int addr_count;
@@ -381,6 +381,8 @@ static struct functable net_func[] = {
{"port", 'p', POPT_ARG_INT, &opt_port},
{"myname", 'n', POPT_ARG_STRING, &opt_requester_name},
{"conf", 's', POPT_ARG_STRING, &servicesf},
+ {"debug", 'd', POPT_ARG_STRING, &debuglevel},
+ {"debuglevel", 'd', POPT_ARG_STRING, &debuglevel},
{"server", 'S', POPT_ARG_STRING, &opt_host},
{"comment", 'C', POPT_ARG_STRING, &opt_comment},
{"maxusers", 'M', POPT_ARG_INT, &opt_maxusers},
@@ -391,7 +393,6 @@ static struct functable net_func[] = {
{"force", 'f', POPT_ARG_NONE, &opt_force},
{"timeout", 't', POPT_ARG_INT, &opt_timeout},
{"machine-pass",'P', POPT_ARG_NONE, &opt_machine_pass},
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug },
{ 0, 0, 0, 0}
};
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index ad405fe68c..fa3eac6bd3 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -32,8 +32,6 @@ int net_ads_usage(int argc, const char **argv)
"\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"\
@@ -60,23 +58,18 @@ static int net_ads_info(int argc, const char **argv)
{
ADS_STRUCT *ads;
- ads = ads_init(NULL, NULL, opt_host);
-
- if (ads) {
- ads->auth.no_bind = 1;
- }
-
+ ads = ads_init(NULL, NULL, opt_host, NULL, NULL);
ads_connect(ads);
- if (!ads || !ads->config.realm) {
+ if (!ads) {
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 server: %s\n", ads->ldap_server);
+ d_printf("LDAP server name: %s\n", ads->ldap_server_name);
+ d_printf("Realm: %s\n", ads->realm);
+ d_printf("Bind Path: %s\n", ads->bind_path);
d_printf("LDAP port: %d\n", ads->ldap_port);
return 0;
@@ -90,7 +83,7 @@ static ADS_STRUCT *ads_startup(void)
BOOL need_password = False;
BOOL second_time = False;
- ads = ads_init(NULL, NULL, opt_host);
+ ads = ads_init(NULL, NULL, opt_host, NULL, NULL);
if (!opt_user_name) {
opt_user_name = "administrator";
@@ -108,9 +101,9 @@ retry:
}
if (opt_password)
- ads->auth.password = strdup(opt_password);
+ ads->password = strdup(opt_password);
- ads->auth.user_name = strdup(opt_user_name);
+ ads->user_name = strdup(opt_user_name);
status = ads_connect(ads);
if (!ADS_ERR_OK(status)) {
@@ -143,38 +136,8 @@ int net_ads_check(void)
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;
- char *workgroup;
-
- if (!(ads = ads_startup())) return -1;
-
- if (!(ctx = talloc_init_named("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 void usergrp_display(char *field, void **values, void *data_area)
+static BOOL usergrp_display(char *field, void **values, void *data_area)
{
char **disp_fields = (char **) data_area;
@@ -188,15 +151,16 @@ static void usergrp_display(char *field, void **values, void *data_area)
}
SAFE_FREE(disp_fields[0]);
SAFE_FREE(disp_fields[1]);
- return;
+ return True;
}
if (!values) /* must be new field, indicate string field */
- return;
+ 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; /* always strings here */
}
static int net_ads_user_usage(int argc, const char **argv)
@@ -244,8 +208,8 @@ static int ads_user_add(int argc, const char **argv)
}
/* try setting the password */
- asprintf(&upn, "%s@%s", argv[0], ads->config.realm);
- status = krb5_set_password(ads->auth.kdc_server, upn, argv[1]);
+ asprintf(&upn, "%s@%s", argv[0], ads->realm);
+ status = krb5_set_password(ads->kdc_server, upn, argv[1]);
safe_free(upn);
if (ADS_ERR_OK(status)) {
d_printf("User %s added\n", argv[0]);
@@ -362,7 +326,7 @@ int net_ads_user(int argc, const char **argv)
d_printf("\nUser name Comment"\
"\n-----------------------------\n");
- rc = ads_do_search_all_fn(ads, ads->config.bind_path,
+ rc = ads_do_search_all_fn(ads, ads->bind_path,
LDAP_SCOPE_SUBTREE,
"(objectclass=user)",
opt_long_list_entries ? longattrs :
@@ -469,7 +433,7 @@ int net_ads_group(int argc, const char **argv)
if (opt_long_list_entries)
d_printf("\nGroup name Comment"\
"\n-----------------------------\n");
- rc = ads_do_search_all_fn(ads, ads->config.bind_path,
+ rc = ads_do_search_all_fn(ads, ads->bind_path,
LDAP_SCOPE_SUBTREE,
"(objectclass=group)",
opt_long_list_entries ? longattrs :
@@ -530,54 +494,15 @@ static int net_ads_leave(int argc, const char **argv)
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);
+ global_myname, ads->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;
- extern pstring global_myname;
-
- if (!secrets_init()) {
- DEBUG(1,("Failed to initialise secrets database\n"));
- return -1;
- }
-
- asprintf(&opt_user_name, "%s$", global_myname);
- opt_password = secrets_fetch_machine_password();
+ d_printf("Removed '%s' from realm '%s'\n", global_myname, ads->realm);
- 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)
-{
- /* 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;
@@ -604,7 +529,7 @@ int net_ads_join(int argc, const char **argv)
if (!(ads = ads_startup())) return -1;
ou_str = ads_ou_string(org_unit);
- asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path);
+ asprintf(&dn, "%s,%s", ou_str, ads->bind_path);
free(ou_str);
rc = ads_search_dn(ads, &res, dn, NULL);
@@ -650,7 +575,7 @@ int net_ads_join(int argc, const char **argv)
return -1;
}
- d_printf("Joined '%s' to realm '%s'\n", global_myname, ads->config.realm);
+ d_printf("Joined '%s' to realm '%s'\n", global_myname, ads->realm);
free(password);
@@ -745,7 +670,7 @@ static int net_ads_printer_publish(int argc, const char **argv)
get_a_printer, because the server name might be
localhost or an ip address */
prt.printerName = argv[0];
- asprintf(&servername, "%s.%s", global_myname, ads->config.realm);
+ asprintf(&servername, "%s.%s", global_myname, ads->realm);
prt.serverName = servername;
prt.shortServerName = global_myname;
prt.versionNumber = "4";
@@ -849,13 +774,13 @@ static int net_ads_password(int argc, const char **argv)
/* 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;
+ if (!(ads = ads_init(realm, NULL, NULL, NULL, NULL))) return -1;
asprintf(&prompt, "Enter new password for %s:", argv[0]);
new_password = getpass(prompt);
- ret = kerberos_set_password(ads->auth.kdc_server, auth_principal,
+ ret = kerberos_set_password(ads->kdc_server, auth_principal,
auth_password, argv[0], new_password);
if (!ADS_ERR_OK(ret)) {
d_printf("Password change failed :-( ...\n");
@@ -880,21 +805,11 @@ static int net_ads_change_localhost_pass(int argc, const char **argv)
char *hostname;
ADS_STATUS ret;
- if (!secrets_init()) {
- DEBUG(1,("Failed to initialise secrets database\n"));
- return -1;
- }
-
- asprintf(&opt_user_name, "%s$", global_myname);
- opt_password = secrets_fetch_machine_password();
-
- if (!(ads = ads_startup())) {
- return -1;
- }
+ if (!(ads = ads_init_simple())) return -1;
hostname = strdup(global_myname);
strlower(hostname);
- asprintf(&host_principal, "%s@%s", hostname, ads->config.realm);
+ asprintf(&host_principal, "%s@%s", hostname, ads->realm);
SAFE_FREE(hostname);
d_printf("Changing password for principal: HOST/%s\n", host_principal);
@@ -953,7 +868,7 @@ static int net_ads_search(int argc, const char **argv)
exp = argv[0];
attrs = (argv + 1);
- rc = ads_do_search_all(ads, ads->config.bind_path,
+ rc = ads_do_search_all(ads, ads->bind_path,
LDAP_SCOPE_SUBTREE,
exp, attrs, &res);
if (!ADS_ERR_OK(rc)) {
@@ -999,7 +914,6 @@ 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},
@@ -1008,7 +922,6 @@ int net_ads(int argc, const char **argv)
{"CHOSTPASS", net_ads_change_localhost_pass},
{"PRINTER", net_ads_printer},
{"SEARCH", net_ads_search},
- {"WORKGROUP", net_ads_workgroup},
{"HELP", net_ads_help},
{NULL, NULL}
};
diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c
index f76b186251..a324f594a1 100644
--- a/source3/utils/net_lookup.c
+++ b/source3/utils/net_lookup.c
@@ -77,8 +77,7 @@ static void print_ldap_srvlist(char *srvlist)
static int net_lookup_ldap(int argc, const char **argv)
{
#ifdef HAVE_LDAP
- char *srvlist;
- const char *domain;
+ char *srvlist, *domain;
int rc, count;
struct in_addr *addr;
struct hostent *hostent;
@@ -126,7 +125,7 @@ static int net_lookup_dc(int argc, const char **argv)
{
struct in_addr *ip_list;
char *pdc_str = NULL;
- const char *domain=opt_target_workgroup;
+ char *domain=opt_target_workgroup;
int count, i;
if (argc > 0)
@@ -155,7 +154,7 @@ static int net_lookup_dc(int argc, const char **argv)
static int net_lookup_master(int argc, const char **argv)
{
struct in_addr master_ip;
- const char *domain=opt_target_workgroup;
+ char *domain=opt_target_workgroup;
if (argc > 0)
domain=argv[0];
@@ -215,8 +214,6 @@ static int net_lookup_kdc(int argc, const char **argv)
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)
{
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 55e8a497cc..dc50c438d4 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -117,21 +117,15 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
* @return A shell status integer (0 for success)
*/
-static int run_rpc_command(struct cli_state *cli_arg, const char *pipe_name, int conn_flags,
- rpc_command_fn fn,
- int argc, const char **argv)
+static int run_rpc_command(const char *pipe_name, int conn_flags,
+ rpc_command_fn fn,
+ int argc, const char **argv)
{
- struct cli_state *cli = NULL;
+ struct cli_state *cli = net_make_ipc_connection(conn_flags);
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
DOM_SID *domain_sid;
- /* 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;
}
@@ -147,7 +141,7 @@ static int run_rpc_command(struct cli_state *cli_arg, const char *pipe_name, int
}
if (!cli_nt_session_open(cli, pipe_name)) {
- DEBUG(0, ("Could not initialise %s pipe\n", pipe_name));
+ DEBUG(0, ("Could not initialise samr pipe\n"));
}
nt_status = fn(domain_sid, cli, mem_ctx, argc, argv);
@@ -162,10 +156,6 @@ static int run_rpc_command(struct cli_state *cli_arg, const char *pipe_name, int
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));
@@ -209,7 +199,7 @@ static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cl
static int rpc_changetrustpw(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
+ return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
argc, argv);
}
@@ -254,7 +244,7 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
trust_passwd[14] = '\0';
- E_md4hash(trust_passwd, orig_trust_passwd_hash);
+ E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash);
}
@@ -271,7 +261,7 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
static int net_rpc_join_oldstyle(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
+ return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
argc, argv);
}
@@ -381,7 +371,7 @@ rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
**/
int net_rpc_info(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
+ return run_rpc_command(PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
rpc_info_internals,
argc, argv);
}
@@ -487,7 +477,7 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_sta
static int rpc_user_add(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_add_internals,
+ return run_rpc_command(PIPE_SAMR, 0, rpc_user_add_internals,
argc, argv);
}
@@ -588,7 +578,7 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
static int rpc_user_delete(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_del_internals,
+ return run_rpc_command(PIPE_SAMR, 0, rpc_user_del_internals,
argc, argv);
}
@@ -690,7 +680,7 @@ rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
static int rpc_user_info(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_info_internals,
+ return run_rpc_command(PIPE_SAMR, 0, rpc_user_info_internals,
argc, argv);
}
@@ -785,7 +775,7 @@ int net_rpc_user(int argc, const char **argv)
if (opt_long_list_entries) {
} else {
}
- return run_rpc_command(NULL,PIPE_SAMR, 0,
+ return run_rpc_command(PIPE_SAMR, 0,
rpc_user_list_internals,
argc, argv);
}
@@ -936,7 +926,7 @@ int net_rpc_group(int argc, const char **argv)
if (opt_long_list_entries) {
} else {
}
- return run_rpc_command(NULL, PIPE_SAMR, 0,
+ return run_rpc_command(PIPE_SAMR, 0,
rpc_group_list_internals,
argc, argv);
}
@@ -994,7 +984,7 @@ static int rpc_share_add(int argc, const char **argv)
DEBUG(1,("Sharename or path not specified on add\n"));
return rpc_share_usage(argc, argv);
}
- return run_rpc_command(NULL, PIPE_SRVSVC, 0,
+ return run_rpc_command(PIPE_SRVSVC, 0,
rpc_share_add_internals,
argc, argv);
}
@@ -1040,7 +1030,7 @@ static int rpc_share_delete(int argc, const char **argv)
DEBUG(1,("Sharename not specified on delete\n"));
return rpc_share_usage(argc, argv);
}
- return run_rpc_command(NULL, PIPE_SRVSVC, 0,
+ return run_rpc_command(PIPE_SRVSVC, 0,
rpc_share_del_internals,
argc, argv);
}
@@ -1130,7 +1120,7 @@ int net_rpc_share(int argc, const char **argv)
};
if (argc == 0)
- return run_rpc_command(NULL, PIPE_SRVSVC, 0,
+ return run_rpc_command(PIPE_SRVSVC, 0,
rpc_share_list_internals,
argc, argv);
@@ -1184,7 +1174,7 @@ static int rpc_file_close(int argc, const char **argv)
return(rpc_file_usage(argc, argv));
}
- return run_rpc_command(NULL, PIPE_SRVSVC, 0,
+ return run_rpc_command(PIPE_SRVSVC, 0,
rpc_file_close_internals,
argc, argv);
}
@@ -1231,13 +1221,13 @@ rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
WERROR result;
ENUM_HND hnd;
uint32 preferred_len = 0xffffffff, i;
- const char *username=NULL;
+ char *username=NULL;
init_enum_hnd(&hnd, 0);
/* if argc > 0, must be user command */
if (argc > 0)
- username = smb_xstrdup(argv[0]);
+ username = argv[0];
result = cli_srvsvc_net_file_enum(
cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
@@ -1275,7 +1265,7 @@ static int rpc_file_user(int argc, const char **argv)
return(rpc_file_usage(argc, argv));
}
- return run_rpc_command(NULL, PIPE_SRVSVC, 0,
+ return run_rpc_command(PIPE_SRVSVC, 0,
rpc_file_list_internals,
argc, argv);
}
@@ -1300,7 +1290,7 @@ int net_rpc_file(int argc, const char **argv)
};
if (argc == 0)
- return run_rpc_command(NULL, PIPE_SRVSVC, 0,
+ return run_rpc_command(PIPE_SRVSVC, 0,
rpc_file_list_internals,
argc, argv);
@@ -1355,7 +1345,7 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct c
static int rpc_shutdown_abort(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_WINREG, 0, rpc_shutdown_abort_internals,
+ return run_rpc_command(PIPE_WINREG, 0, rpc_shutdown_abort_internals,
argc, argv);
}
@@ -1445,7 +1435,7 @@ static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_sta
static int rpc_shutdown(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_WINREG, 0, rpc_shutdown_internals,
+ return run_rpc_command(PIPE_WINREG, 0, rpc_shutdown_internals,
argc, argv);
}
@@ -1470,7 +1460,7 @@ static int rpc_shutdown(int argc, const char **argv)
*/
static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
+ int argc, const char **argv) {
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -1493,14 +1483,16 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli
strupper(acct_name);
- /* Get samr policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ /* 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);
@@ -1509,9 +1501,10 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli
}
/* Create trusting domain's account */
+
acb_info = ACB_DOMTRUST;
- unknown = 0xe005000b; /* No idea what this is - a permission mask?
- mimir: yes, most probably it is */
+ unknown = 0xe005000b; /* No idea what this is - a permission mask?
+ Is it needed for interdomain account also ? */
result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
acct_name, acb_info, unknown,
@@ -1536,7 +1529,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli
static int rpc_trustdom_add(int argc, const char **argv)
{
- return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_trustdom_add_internals,
+ return run_rpc_command(PIPE_SAMR, 0, rpc_trustdom_add_internals,
argc, argv);
}
@@ -1569,10 +1562,9 @@ static int rpc_trustdom_del(int argc, const char **argv)
extern char *opt_user_name;
extern char *opt_password;
-extern char *opt_workgroup;
-static int rpc_trustdom_establish(int argc, const char **argv)
-{
+static int rpc_trustdom_establish(int argc, const char **argv) {
+
struct cli_state *cli;
struct in_addr server_ip;
POLICY_HND connect_hnd;
@@ -1590,26 +1582,19 @@ static int rpc_trustdom_establish(int argc, const char **argv)
*/
if (argc != 1) {
- d_printf("Usage: net rpc trustdom establish <domain_name>\n");
+ d_printf("Usage: net rpc trustdom add <domain_name>\n");
return -1;
}
+
domain_name = smb_xstrdup(argv[0]);
strupper(domain_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) {
- SAFE_FREE(opt_workgroup);
- opt_workgroup = smb_xstrdup(domain_name);
- };
-
asprintf(&acct_name, "%s$", lp_workgroup());
strupper(acct_name);
- opt_user_name = acct_name;
+ opt_user_name = (char*)malloc(strlen(acct_name) + 1);
+ safe_strcpy(opt_user_name, acct_name, strlen(acct_name) + 1);
/* find the domain controller */
if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
@@ -1649,7 +1634,10 @@ static int rpc_trustdom_establish(int argc, const char **argv)
/*
* Call WksQueryInfo to check remote server's capabilities
- * note: It is now used only to get unicode domain name
+ * FIXME:Is really necessary ? nt serv does this, but from samba's
+ * point of view it doesn't seem to make the difference
+ * IDEA: It may be used to get info about type of pdc we're talking to
+ * (e.g. WinNT or Win2k)
*/
if (!cli_nt_session_open(cli, PIPE_WKSSVC)) {
@@ -1657,8 +1645,12 @@ static int rpc_trustdom_establish(int argc, const char **argv)
return -1;
}
- if (!(mem_ctx = talloc_init_named("establishing trust relationship to domain %s",
- domain_name))) {
+ /* TODO: convert this call from rpc_client/cli_wkssvc.c
+ to cli_wks_query_info() in libsmb/cli_wkssvc.c
+ UPDATE: already done :)
+ */
+
+ if (!(mem_ctx = talloc_init())) {
DEBUG(0, ("talloc_init() failed\n"));
cli_shutdown(cli);
return -1;
@@ -1687,12 +1679,10 @@ static int rpc_trustdom_establish(int argc, const char **argv)
if (!cli_nt_session_open(cli, PIPE_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);
+ &connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
nt_errstr(nt_status)));
@@ -1702,8 +1692,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
/* Querying info level 5 */
nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
- 5 /* info level */, domain_name,
- &domain_sid);
+ 5 /* info level */, domain_name, &domain_sid);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
nt_errstr(nt_status)));
@@ -1711,8 +1700,6 @@ static int rpc_trustdom_establish(int argc, const char **argv)
}
-
-
/* There should be actually query info level 3 (following nt serv behaviour),
but I still don't know if it's _really_ necessary */
@@ -1756,8 +1743,8 @@ static int rpc_trustdom_establish(int argc, const char **argv)
* @return Integer status (0 means success)
**/
-static int rpc_trustdom_revoke(int argc, const char **argv)
-{
+static int rpc_trustdom_revoke(int argc, const char **argv) {
+
char* domain_name;
if (argc < 1) return -1;
@@ -1785,8 +1772,7 @@ static int rpc_trustdom_revoke(int argc, const char **argv)
* @return Integer status returned to shell
**/
-static int rpc_trustdom_usage(int argc, const char **argv)
-{
+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");
@@ -1796,249 +1782,6 @@ static int rpc_trustdom_usage(int argc, const char **argv)
}
-static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, 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;
-};
-
-
-extern char* opt_workgroup;
-extern char* opt_target_worgroup;
-extern char* opt_host;
-extern char* opt_password;
-
-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;
- 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 */
- int enum_ctx = 0;
- int num_domains, i, pad_len, col_len = 20;
- DOM_SID *domain_sids;
- char **trusted_dom_names;
- fstring pdc_name;
-
- /* 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_named("trust relationships listing");
-
- /*
- * set domain and pdc name to local samba server (default)
- * or to remote one given in command line
- */
- strupper(opt_workgroup);
- if (strcmp(opt_workgroup, lp_workgroup())) {
- domain_name = opt_workgroup;
- if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup);
- opt_target_workgroup = opt_workgroup;
- } else {
- safe_strcpy(pdc_name, global_myname, FSTRING_LEN);
- domain_name = talloc_strdup(mem_ctx, lp_workgroup());
- if (opt_target_workgroup) SAFE_FREE(opt_target_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, PIPE_LSARPC)) {
- DEBUG(0, ("Could not initialise lsa pipe\n"));
- 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;
- };
-
- /* 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 */, domain_name, &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);
- };
-
- } 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, PIPE_SAMR)) {
- DEBUG(0, ("Could not initialise samr pipe\n"));
- return -1;
- };
-
- /* SamrConnect */
- nt_status = cli_samr_connect(cli, mem_ctx, SAMR_ACCESS_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,
- DOMAIN_ACCESS_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(trusting_dom_names[i]);
- opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
- if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup);
- 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, PIPE_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");
- };
- };
-
- } 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
*
@@ -2056,7 +1799,6 @@ static int rpc_trustdom(int argc, const char **argv)
{"establish", rpc_trustdom_establish},
{"revoke", rpc_trustdom_revoke},
{"help", rpc_trustdom_usage},
- {"list", rpc_trustdom_list},
{NULL, NULL}
};
@@ -2120,7 +1862,6 @@ 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 testjoin \t\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 group \t\tto list groups\n");
d_printf(" net rpc share \t\tto add, delete, and list shares\n");
@@ -2183,7 +1924,6 @@ int net_rpc(int argc, const char **argv)
struct functable func[] = {
{"info", net_rpc_info},
{"join", net_rpc_join},
- {"testjoin", net_rpc_testjoin},
{"user", net_rpc_user},
{"group", net_rpc_group},
{"share", net_rpc_share},
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index c8be93c39c..cc1a203ca1 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -35,61 +35,6 @@
goto done; \
}
-
-/**
- * confirm that a domain join is still valid
- *
- * @return A shell status integer (0 for success)
- *
- **/
-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, PIPE_NETLOGON)) {
- DEBUG(0,("Error connecting to NETLOGON pipe\n"));
- goto done;
- }
-
- if (!secrets_fetch_trust_account_password(domain,
- stored_md4_trust_password, NULL)) {
- DEBUG(0,("Could not reterive domain trust secret"));
- goto done;
- }
-
- if (lp_server_role() == ROLE_DOMAIN_BDC ||
- lp_server_role() == ROLE_DOMAIN_PDC) {
- channel = SEC_CHAN_BDC;
- } else {
- channel = SEC_CHAN_WKSTA;
- }
-
- CHECK_RPC_ERR(cli_nt_setup_creds(cli,
- channel,
- stored_md4_trust_password),
- "error in domain join verification");
-
- 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
*
@@ -122,6 +67,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
char *clear_trust_password = NULL;
fstring ucs2_trust_password;
int ucs2_pw_len;
+ uchar stored_md4_trust_password[16];
uchar pwbuf[516], sess_key[16];
SAM_USERINFO_CTR ctr;
SAM_USER_INFO_24 p24;
@@ -134,9 +80,8 @@ int net_rpc_join_newstyle(int argc, const char **argv)
fstring domain;
uint32 num_rids, *name_types, *user_rids;
uint32 flags = 0x3e8;
- char *acct_name;
- const char *const_acct_name;
-
+ const char *acct_name;
+
/* Connect to remote machine */
if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC)))
@@ -188,7 +133,6 @@ int net_rpc_join_newstyle(int argc, const char **argv)
/* Create domain user */
acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname);
strlower(acct_name);
- const_acct_name = acct_name;
acb_info = ((lp_server_role() == ROLE_DOMAIN_BDC) || lp_server_role() == ROLE_DOMAIN_PDC) ? ACB_SVRTRUST : ACB_WSTRUST;
@@ -218,8 +162,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
CHECK_RPC_ERR_DEBUG(cli_samr_lookup_names(cli, mem_ctx,
&domain_pol, flags,
- 1, &const_acct_name,
- &num_rids,
+ 1, &acct_name, &num_rids,
&user_rids, &name_types),
("error looking up rid for user %s: %s\n",
acct_name, nt_errstr(result)));
@@ -310,10 +253,28 @@ int net_rpc_join_newstyle(int argc, const char **argv)
}
/* 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 */
- retval = net_rpc_join_ok(domain);
+ if (!cli_nt_session_open(cli, PIPE_NETLOGON)) {
+ DEBUG(0, ("Error connecting to NETLOGON pipe\n"));
+ goto done;
+ }
+
+ if (!secrets_fetch_trust_account_password(domain,
+ stored_md4_trust_password, NULL)) {
+ DEBUG(0, ("Could not reterive secrets we just stored!"));
+ goto done;
+ }
+
+ CHECK_RPC_ERR(new_cli_nt_setup_creds(cli,
+ (acb_info & ACB_SVRTRUST) ? SEC_CHAN_BDC : SEC_CHAN_WKSTA,
+ stored_md4_trust_password),
+ "error in domain join verification");
+
+ retval = 0; /* Success! */
done:
/* Close down pipe - this will clean up open policy handles */
@@ -336,28 +297,3 @@ done:
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 = lp_workgroup();
-
- domain = smb_xstrdup(domain);
-
- /* 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/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index 51dbbb98c0..b30ab6f38e 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -23,35 +23,6 @@
#include "includes.h"
-#define BIT_CONFIGFILE 0x00000001
-#define BIT_DEBUGLEVEL 0x00000002
-#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_RESERV_6 0x00400000
-#define BIT_RESERV_7 0x00800000
-#define BIT_IMPORT 0x01000000
-#define BIT_EXPORT 0x02000000
-
-#define MASK_ALWAYS_GOOD 0x0000001F
-#define MASK_USER_GOOD 0x00001F00
extern pstring global_myname;
extern BOOL AllowDebugChange;
@@ -59,21 +30,27 @@ extern BOOL AllowDebugChange;
Add all currently available users to another db
********************************************************/
-static int export_database (struct pdb_context *in, struct pdb_context *out) {
+int export_database (struct pdb_context *in, char *db){
+ struct pdb_context *context;
SAM_ACCOUNT *user = NULL;
- if (!in->pdb_setsampwent(in, 0)) {
+ if (!NT_STATUS_IS_OK(make_pdb_context_string(&context, db))){
+ fprintf(stderr, "Can't initialize %s.\n", db);
+ return 1;
+ }
+
+ if (!in->pdb_setsampwent(in, 0)){
fprintf(stderr, "Can't sampwent!\n");
return 1;
}
- if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
+ if (!NT_STATUS_IS_OK(pdb_init_sam(&user))){
fprintf(stderr, "Can't initialize new SAM_ACCOUNT!\n");
return 1;
}
- while (in->pdb_getsampwent(in, user)) {
- out->pdb_add_sam_account(out, user);
+ while (in->pdb_getsampwent(in,user)){
+ context->pdb_add_sam_account(context,user);
if (!NT_STATUS_IS_OK(pdb_reset_sam(user))){
fprintf(stderr, "Can't reset SAM_ACCOUNT!\n");
return 1;
@@ -114,7 +91,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst
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 ("HomeDir Drive: %s\n", pdb_get_dirdrive(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));
@@ -278,7 +255,7 @@ static int new_user (struct pdb_context *in, char *username, char *fullname, cha
{
SAM_ACCOUNT *sam_pwent=NULL;
struct passwd *pwd = NULL;
- char *password1, *password2, *staticpass;
+ char *password1, *password2;
ZERO_STRUCT(sam_pwent);
@@ -293,27 +270,15 @@ static int new_user (struct pdb_context *in, char *username, char *fullname, cha
}
}
- 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));
+ password1 = getpass("new password:");
+ password2 = getpass("retype new password:");
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;
+ fprintf (stderr, "Passwords does 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);
if (fullname)
pdb_set_fullname(sam_pwent, fullname);
@@ -419,7 +384,7 @@ static int delete_machine_entry (struct pdb_context *in, char *machinename)
}
if (!in->pdb_getsampwnam(in, samaccount, name)) {
- fprintf (stderr, "machine %s does not exist in the passdb\n", name);
+ fprintf (stderr, "user %s does not exist in the passdb\n", name);
return -1;
}
@@ -435,230 +400,129 @@ int main (int argc, char **argv)
static BOOL list_users = False;
static BOOL verbose = False;
static BOOL spstyle = False;
+ static BOOL setparms = False;
static BOOL machine = False;
static BOOL add_user = False;
static BOOL delete_user = False;
- static BOOL modify_user = False;
- uint32 setparms, checkparms;
+ static BOOL import = False;
int opt;
static char *full_name = NULL;
static 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 char *logon_script = NULL;
static char *profile_path = NULL;
static char *config_file = dyn_CONFIGFILE;
static char *new_debuglevel = NULL;
- static char *account_policy = NULL;
- static long int account_policy_value = 0;
- BOOL account_policy_value_set = False;
- struct pdb_context *bin;
- struct pdb_context *bout;
- struct pdb_context *bdef;
+ struct pdb_context *in;
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},
- {"create", 'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL},
- {"modify", 'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL},
- {"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL},
- {"delete", 'x', POPT_ARG_NONE, &delete_user, 0, "delete user", 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},
- {"debuglevel", 'D', POPT_ARG_STRING, &new_debuglevel, 0,"set debuglevel",NULL},
- {"configfile", 'c', POPT_ARG_STRING, &config_file, 0,"use different configuration file",NULL},
- {"account-policy", 'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL},
- {"value", 'V', POPT_ARG_LONG, &account_policy_value, 'V',"set the account policy to this value", NULL},
+ {"list", 'l',POPT_ARG_VAL, &list_users, 1, "list all users", NULL},
+ {"verbose", 'v',POPT_ARG_VAL, &verbose, 1, "be verbose", NULL },
+ {"smbpasswd-style", 'w',POPT_ARG_VAL, &spstyle, 1, "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},
+ {"create", 'a',POPT_ARG_VAL,&add_user, 1, "create user", NULL},
+ {"machine", 'm',POPT_ARG_VAL,&machine, 1,"account is a machine account",NULL},
+ {"delete", 'x',POPT_ARG_VAL,&delete_user,1,"delete user",NULL},
+ {"import", 'i',POPT_ARG_STRING,&backend_in,0,"use different passdb backend",NULL},
+ {"export", 'e',POPT_ARG_STRING,&backend_out,0,"export user accounts to backend", NULL},
+ {"debuglevel",'D', POPT_ARG_STRING, &new_debuglevel,0,"set debuglevel",NULL},
+ {"configfile",'c',POPT_ARG_STRING, &config_file,0,"use different configuration file",NULL},
{0,0,0,0}
};
-
+
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 'V':
- account_policy_value_set = True;
- break;
- }
- }
-
- if (new_debuglevel) {
+ POPT_CONTEXT_KEEP_FIRST);
+
+ while((opt = poptGetNextOpt(pc)) != -1);
+
+ if (new_debuglevel){
debug_parse_levels(new_debuglevel);
AllowDebugChange = False;
}
-
+
if (!lp_load(config_file,True,False,False)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", config_file);
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+ config_file);
exit(1);
}
- setparms = (config_file ? BIT_CONFIGFILE : 0) +
- (new_debuglevel ? BIT_DEBUGLEVEL : 0) +
- (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) +
- (user_name ? BIT_USER : 0) +
- (list_users ? BIT_LIST : 0) +
- (modify_user ? BIT_MODIFY : 0) +
- (add_user ? BIT_CREATE : 0) +
- (delete_user ? BIT_DELETE : 0) +
- (account_policy ? BIT_ACCPOLICY : 0) +
- (account_policy_value_set ? BIT_ACCPOLVAL : 0) +
- (backend_in ? BIT_IMPORT : 0) +
- (backend_out ? BIT_EXPORT : 0);
-
- if (setparms & BIT_BACKEND) {
- if (!NT_STATUS_IS_OK(make_pdb_context_string(&bdef, backend))) {
+
+ setparms = (full_name || home_dir || home_drive || logon_script || profile_path);
+
+ if (((add_user?1:0) + (delete_user?1:0) + (list_users?1:0) + (import?1:0) + (setparms?1:0)) + (backend_out?1:0) > 1) {
+ fprintf (stderr, "Incompatible options on command line!\n");
+ exit(1);
+ }
+
+ if (!backend_in) {
+ if (!NT_STATUS_IS_OK(make_pdb_context_list(&in, lp_passdb_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()))) {
+ if (!NT_STATUS_IS_OK(make_pdb_context_string(&in, backend_in))){
fprintf(stderr, "Can't initialize passdb backend.\n");
return 1;
}
}
-
- /* the lowest bit options are always accepted */
- checkparms = setparms & ~MASK_ALWAYS_GOOD;
-
- /* accoun tpolicy 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);
- }
- }
- /* 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 (add_user) {
+ if (!user_name) {
+ fprintf (stderr, "Username not specified! (use -u option)\n");
+ return -1;
}
- return export_database(bin, bout);
+ if (machine)
+ return new_machine (in, user_name);
+ else
+ return new_user (in, user_name, full_name, home_dir,
+ home_drive, logon_script,
+ profile_path);
}
- /* 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;
- }
-
- /* list users operations */
- if (checkparms & BIT_LIST) {
- if (!(checkparms & ~BIT_LIST)) {
- return print_users_list (bdef, verbose, spstyle);
- }
- if (!(checkparms & ~(BIT_USER + BIT_LIST))) {
- return print_user_info (bdef, user_name, verbose, spstyle);
- }
- }
-
- /* mask out users options */
- checkparms &= ~MASK_USER_GOOD;
-
- /* account operation */
- if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
- /* check use of -u option */
- if (!(checkparms & BIT_USER)) {
+ if (delete_user) {
+ if (!user_name) {
fprintf (stderr, "Username not specified! (use -u option)\n");
return -1;
}
+ if (machine)
+ return delete_machine_entry (in, user_name);
+ else
+ return delete_user_entry (in, user_name);
+ }
- /* account creation operations */
- if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) {
- if (checkparms & BIT_MACHINE) {
- return new_machine (bdef, user_name);
- } else {
- return new_user (bdef, user_name, full_name, home_dir,
- home_drive, logon_script,
- profile_path);
- }
- }
-
- /* 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,
+ if (user_name) {
+ if (setparms)
+ return set_user_info (in, user_name, full_name,
home_dir,
home_drive,
logon_script,
profile_path);
- }
+ else
+ return print_user_info (in, user_name, verbose,
+ spstyle);
}
- if (setparms >= 0x20) {
- fprintf (stderr, "Incompatible or insufficient options on command line!\n");
- }
+ if (list_users)
+ return print_users_list (in, verbose, spstyle);
+
+ if (backend_out)
+ return export_database(in, backend_out);
+
poptPrintHelp(pc, stderr, 0);
return 1;
}
+
+
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 4f9df90fa2..b6a13180a3 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -29,7 +29,7 @@ static pstring owner_username;
static fstring server;
static int got_pass;
static int test_args;
-static TALLOC_CTX *ctx;
+TALLOC_CTX *ctx;
#define CREATE_ACCESS_READ READ_CONTROL_ACCESS
#define CREATE_ACCESS_WRITE (WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS)
diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c
index 2d78b21dcc..65519e8888 100644
--- a/source3/utils/smbcontrol.c
+++ b/source3/utils/smbcontrol.c
@@ -223,23 +223,6 @@ static void register_all(void)
message_register(MSG_POOL_USAGE, pool_usage_cb);
}
-/* This guy is here so we can link printing/notify.c to the smbcontrol
- binary without having to pull in tons of other crap. */
-
-TDB_CONTEXT *conn_tdb_ctx(void)
-{
- static TDB_CONTEXT *tdb;
-
- if (tdb)
- return tdb;
-
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
-
- if (!tdb)
- DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n"));
-
- return tdb;
-}
/****************************************************************************
do command
@@ -369,9 +352,6 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
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");
return False;
}
diff --git a/source3/utils/smbgroupedit.c b/source3/utils/smbgroupedit.c
index 4358e6f08c..3fdc07c2d5 100644
--- a/source3/utils/smbgroupedit.c
+++ b/source3/utils/smbgroupedit.c
@@ -22,7 +22,7 @@
#include "includes.h"
extern pstring global_myname;
-extern fstring global_myworkgroup;
+extern pstring global_myworkgroup;
/*
* Next two lines needed for SunOS and don't
@@ -45,13 +45,11 @@ static void usage(void)
printf(" -a group create new group\n");
printf(" -n group NT group name\n");
printf(" -p privilege only local\n");
- printf(" -d description group description\n");
printf(" -v list groups\n");
printf(" -l long list (include details)\n");
printf(" -s short list (default)\n");
printf(" -c SID change group\n");
printf(" -u unix group\n");
- printf(" -d description group description\n");
printf(" -x group delete this group\n");
printf("\n");
printf(" -t[b|d|l] type: builtin, domain, local \n");
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index 98993676c9..70bf551edb 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -92,7 +92,7 @@ static int process_options(int argc, char **argv, int local_flags)
user_name[0] = '\0';
- while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:L")) != EOF) {
+ while ((ch = getopt(argc, argv, "c:axdehmnjr:sw:R:D:U:L")) != EOF) {
switch(ch) {
case 'L':
local_flags |= LOCAL_AM_ROOT;
@@ -416,11 +416,9 @@ static int process_root(int local_flags)
exit(1);
}
}
-
- /* prepare uppercased and '$' terminated username */
slprintf(buf, sizeof(buf) - 1, "%s$", user_name);
fstrcpy(user_name, buf);
-
+
} else {
if (remote_machine != NULL) {
diff --git a/source3/utils/smbtree.c b/source3/utils/smbtree.c
index b733f8112f..bcb460ee0b 100644
--- a/source3/utils/smbtree.c
+++ b/source3/utils/smbtree.c
@@ -32,7 +32,7 @@ struct user_auth_info {
/* How low can we go? */
enum tree_level {LEV_WORKGROUP, LEV_SERVER, LEV_SHARE};
-static enum tree_level level = LEV_SHARE;
+enum tree_level level = LEV_SHARE;
static void usage(void)
{
diff --git a/source3/utils/status.c b/source3/utils/status.c
index 0b0c591cb1..b1e8bb9d8e 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -37,6 +37,14 @@
extern BOOL AllowDebugChange;
+struct session_record{
+ pid_t pid;
+ uid_t uid;
+ char machine[31];
+ time_t start;
+ struct session_record *next;
+} *srecs;
+
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 */
@@ -551,7 +559,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
{"brief", 'b', POPT_ARG_NONE, &brief},
{"profile", 'P', POPT_ARG_NONE, &profile_only},
{"byterange", 'B', POPT_ARG_NONE, &show_brl},
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug },
+ {"debug", 'd', POPT_ARG_STRING, &new_debuglevel},
{ 0, 0, 0, 0}
};
diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
index 3086019467..1d48249a75 100644
--- a/source3/utils/testparm.c
+++ b/source3/utils/testparm.c
@@ -175,6 +175,7 @@ int main(int argc, char *argv[])
{
extern char *optarg;
extern int optind;
+ extern fstring local_machine;
const char *config_file = dyn_CONFIGFILE;
int s;
static BOOL silent_mode = False;
@@ -182,7 +183,7 @@ int main(int argc, char *argv[])
int opt;
poptContext pc;
static char *term_code = "";
- static char *new_local_machine = NULL;
+ static char *new_local_machine = local_machine;
const char *cname;
const char *caddr;
@@ -206,10 +207,8 @@ int main(int argc, char *argv[])
cname = poptGetArg(pc);
caddr = poptGetArg(pc);
-
- if (new_local_machine) {
- set_local_machine_name(new_local_machine);
- }
+
+ fstrcpy(local_machine,new_local_machine);
dbf = x_stdout;
DEBUGLEVEL = 2;
diff --git a/source3/web/diagnose.c b/source3/web/diagnose.c
index 396499bcb9..e822474aab 100644
--- a/source3/web/diagnose.c
+++ b/source3/web/diagnose.c
@@ -21,23 +21,6 @@
#include "includes.h"
#include "../web/swat_proto.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)
-{
-
- if (winbindd_request(WINBINDD_PING, NULL, NULL))
- return False;
-
- return True;
-}
-#endif
/* check to see if nmbd is running on localhost by looking for a __SAMBA__
response */
diff --git a/source3/web/neg_lang.c b/source3/web/neg_lang.c
index da974f78a4..88bc5498e9 100644
--- a/source3/web/neg_lang.c
+++ b/source3/web/neg_lang.c
@@ -48,70 +48,20 @@ int web_open(const char *fname, int flags, mode_t 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)
+void web_set_lang(const char *lang_list)
{
- 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;
+ fstring lang;
+ char *p = (char *)lang_list;
- /* 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]);
+ while (next_token(&p, lang, ", \t\r\n", sizeof(lang))) {
+ if (lang_tdb_init(lang)) return;
}
- 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/source3/web/startstop.c b/source3/web/startstop.c
index e10dff4118..893784dd55 100644
--- a/source3/web/startstop.c
+++ b/source3/web/startstop.c
@@ -67,27 +67,6 @@ void start_nmbd(void)
exit(0);
}
-/** Startup winbindd from web interface. */
-void start_winbindd(void)
-{
- pstring binfile;
-
- if (geteuid() != 0) return;
-
- if (fork()) {
- sleep(SLEEP_TIME);
- return;
- }
-
- slprintf(binfile, sizeof(pstring) - 1, "%s/winbindd", dyn_SBINDIR);
-
- become_daemon();
-
- execl(binfile, binfile, NULL);
-
- exit(0);
-}
-
/* stop smbd */
void stop_smbd(void)
@@ -112,19 +91,7 @@ void stop_nmbd(void)
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)
{
diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c
index 3b597d44c0..792e077a61 100644
--- a/source3/web/statuspage.c
+++ b/source3/web/statuspage.c
@@ -248,20 +248,6 @@ void status_page(void)
stop_nmbd();
}
-#ifdef WITH_WINBIND
- if (cgi_variable("winbindd_restart")) {
- stop_winbindd();
- start_winbindd();
- }
-
- if (cgi_variable("winbindd_start")) {
- start_winbindd();
- }
-
- if (cgi_variable("winbindd_stop")) {
- stop_winbindd();
- }
-#endif
if (cgi_variable("autorefresh")) {
autorefresh = 1;
} else if (cgi_variable("norefresh")) {
@@ -334,20 +320,6 @@ void status_page(void)
}
d_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()) {
- 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
-
d_printf("</table>\n");
fflush(stdout);
diff --git a/source3/web/swat.c b/source3/web/swat.c
index 80d3232d2b..7be46790db 100644
--- a/source3/web/swat.c
+++ b/source3/web/swat.c
@@ -79,15 +79,15 @@ static char *fix_backslash(char *str)
return newstring;
}
-static char *stripspaceupper(char *str)
+static char *stripspace(char *str)
{
- static char newstring[1024];
- char *p = newstring;
+static char newstring[1024];
+char *p = newstring;
- while (*str) {
- if (*str != ' ') *p++ = toupper(*str);
- ++str;
- }
+ while (*str) {
+ if (*str != ' ') *p++ = *str;
+ ++str;
+ }
*p = '\0';
return newstring;
}
@@ -200,7 +200,7 @@ static void show_parameter(int snum, struct parm_struct *parm)
ptr = lp_local_ptr(snum, ptr);
}
- printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
+ printf("<tr><td>%s</td><td>", get_parm_translated(stripspace(parm->label), _("Help"), parm->label));
switch (parm->type) {
case P_CHAR:
d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
diff --git a/source3/wrepld/process.c b/source3/wrepld/process.c
index 56013d2e17..7615b8c78a 100644
--- a/source3/wrepld/process.c
+++ b/source3/wrepld/process.c
@@ -152,7 +152,7 @@ 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);
+ char **partner = str_list_make(lp_wins_partners());
if (partner==NULL) {
DEBUG(0,("wrepld: no partner list in smb.conf, exiting\n"));
diff --git a/source3/wrepld/server.c b/source3/wrepld/server.c
index 14d3e730f4..740003035c 100644
--- a/source3/wrepld/server.c
+++ b/source3/wrepld/server.c
@@ -26,6 +26,7 @@ extern pstring global_myname;
extern pstring user_socket_options;
+extern fstring remote_machine;
extern WINS_OWNER *global_wins_table;
extern int partner_count;
@@ -636,7 +637,7 @@ static void process(void)
lp_set_logfile(logfile);
}
- set_remote_machine_name("wrepld");
+ pstrcpy(remote_machine, "wrepld");
setup_logging(argv[0],interactive);